@@ -43,7 +43,7 @@ let debug = require('internal/util/debuglog').debuglog('net', (fn) => {
43
43
debug = fn ;
44
44
} ) ;
45
45
const {
46
- kWrapConnectedHandle ,
46
+ kReinitializeHandle ,
47
47
isIP,
48
48
isIPv4,
49
49
isIPv6,
@@ -55,6 +55,7 @@ const {
55
55
UV_EADDRINUSE ,
56
56
UV_EINVAL ,
57
57
UV_ENOTCONN ,
58
+ UV_ECANCELED ,
58
59
} = internalBinding ( 'uv' ) ;
59
60
60
61
const { Buffer } = require ( 'buffer' ) ;
@@ -132,6 +133,7 @@ let dns;
132
133
let BlockList ;
133
134
let SocketAddress ;
134
135
let autoSelectFamilyDefault = getOptionValue ( '--enable-network-family-autoselection' ) ;
136
+ let autoSelectFamilyAttemptTimeoutDefault = 250 ;
135
137
136
138
const { clearTimeout, setTimeout } = require ( 'timers' ) ;
137
139
const { kTimeout } = require ( 'internal/timers' ) ;
@@ -254,6 +256,20 @@ function setDefaultAutoSelectFamily(value) {
254
256
autoSelectFamilyDefault = value ;
255
257
}
256
258
259
+ function getDefaultAutoSelectFamilyAttemptTimeout ( ) {
260
+ return autoSelectFamilyAttemptTimeoutDefault ;
261
+ }
262
+
263
+ function setDefaultAutoSelectFamilyAttemptTimeout ( value ) {
264
+ validateInt32 ( value , 'value' , 1 ) ;
265
+
266
+ if ( value < 1 ) {
267
+ value = 10 ;
268
+ }
269
+
270
+ autoSelectFamilyAttemptTimeoutDefault = value ;
271
+ }
272
+
257
273
// Returns an array [options, cb], where options is an object,
258
274
// cb is either a function or null.
259
275
// Used to normalize arguments of Socket.prototype.connect() and
@@ -694,7 +710,11 @@ function tryReadStart(socket) {
694
710
695
711
// Just call handle.readStart until we have enough in the buffer
696
712
Socket . prototype . _read = function ( n ) {
697
- debug ( '_read' ) ;
713
+ debug (
714
+ '_read - n' , n ,
715
+ 'isConnecting?' , ! ! this . connecting ,
716
+ 'hasHandle?' , ! ! this . _handle ,
717
+ ) ;
698
718
699
719
if ( this . connecting || ! this . _handle ) {
700
720
debug ( '_read wait for connection' ) ;
@@ -1034,7 +1054,7 @@ function internalConnect(
1034
1054
localAddress = localAddress || DEFAULT_IPV6_ADDR ;
1035
1055
err = self . _handle . bind6 ( localAddress , localPort , flags ) ;
1036
1056
}
1037
- debug ( 'binding to localAddress: %s and localPort: %d (addressType: %d)' ,
1057
+ debug ( 'connect: binding to localAddress: %s and localPort: %d (addressType: %d)' ,
1038
1058
localAddress , localPort , addressType ) ;
1039
1059
1040
1060
err = checkBindError ( err , localPort , self . _handle ) ;
@@ -1045,6 +1065,8 @@ function internalConnect(
1045
1065
}
1046
1066
}
1047
1067
1068
+ debug ( 'connect: attempting to connect to %s:%d (addressType: %d)' , address , port , addressType ) ;
1069
+
1048
1070
if ( addressType === 6 || addressType === 4 ) {
1049
1071
const req = new TCPConnectWrap ( ) ;
1050
1072
req . oncomplete = afterConnect ;
@@ -1081,17 +1103,17 @@ function internalConnect(
1081
1103
}
1082
1104
1083
1105
1084
- function internalConnectMultiple ( context ) {
1106
+ function internalConnectMultiple ( context , canceled ) {
1085
1107
clearTimeout ( context [ kTimeout ] ) ;
1086
1108
const self = context . socket ;
1087
- assert ( self . connecting ) ;
1088
1109
1089
1110
// All connections have been tried without success, destroy with error
1090
- if ( context . current === context . addresses . length ) {
1111
+ if ( canceled || context . current === context . addresses . length ) {
1091
1112
self . destroy ( aggregateErrors ( context . errors ) ) ;
1092
1113
return ;
1093
1114
}
1094
1115
1116
+ assert ( self . connecting ) ;
1095
1117
1096
1118
const current = context . current ++ ;
1097
1119
const handle = current === 0 ? self . _handle : new TCP ( TCPConstants . SOCKET ) ;
@@ -1120,6 +1142,8 @@ function internalConnectMultiple(context) {
1120
1142
}
1121
1143
}
1122
1144
1145
+ debug ( 'connect/multiple: attempting to connect to %s:%d (addressType: %d)' , address , port , addressType ) ;
1146
+
1123
1147
const req = new TCPConnectWrap ( ) ;
1124
1148
req . oncomplete = FunctionPrototypeBind ( afterConnectMultiple , undefined , context , current ) ;
1125
1149
req . address = address ;
@@ -1213,6 +1237,15 @@ Socket.prototype.connect = function(...args) {
1213
1237
return this ;
1214
1238
} ;
1215
1239
1240
+ Socket . prototype [ kReinitializeHandle ] = function reinitializeHandle ( handle ) {
1241
+ this . _handle ?. close ( ) ;
1242
+
1243
+ this . _handle = handle ;
1244
+ this . _handle [ owner_symbol ] = this ;
1245
+
1246
+ initSocketHandle ( this ) ;
1247
+ } ;
1248
+
1216
1249
function socketToDnsFamily ( family ) {
1217
1250
switch ( family ) {
1218
1251
case 'IPv4' :
@@ -1260,7 +1293,7 @@ function lookupAndConnect(self, options) {
1260
1293
autoSelectFamilyAttemptTimeout = 10 ;
1261
1294
}
1262
1295
} else {
1263
- autoSelectFamilyAttemptTimeout = 250 ;
1296
+ autoSelectFamilyAttemptTimeout = autoSelectFamilyAttemptTimeoutDefault ;
1264
1297
}
1265
1298
1266
1299
// If host is an IP, skip performing a lookup
@@ -1302,17 +1335,19 @@ function lookupAndConnect(self, options) {
1302
1335
debug ( 'connect: autodetecting' ) ;
1303
1336
1304
1337
dnsopts . all = true ;
1305
- lookupAndConnectMultiple (
1306
- self ,
1307
- async_id_symbol ,
1308
- lookup ,
1309
- host ,
1310
- options ,
1311
- dnsopts ,
1312
- port ,
1313
- localPort ,
1314
- autoSelectFamilyAttemptTimeout ,
1315
- ) ;
1338
+ defaultTriggerAsyncIdScope ( self [ async_id_symbol ] , function ( ) {
1339
+ lookupAndConnectMultiple (
1340
+ self ,
1341
+ async_id_symbol ,
1342
+ lookup ,
1343
+ host ,
1344
+ options ,
1345
+ dnsopts ,
1346
+ port ,
1347
+ localPort ,
1348
+ autoSelectFamilyAttemptTimeout ,
1349
+ ) ;
1350
+ } ) ;
1316
1351
1317
1352
return ;
1318
1353
}
@@ -1360,6 +1395,8 @@ function lookupAndConnectMultiple(self, async_id_symbol, lookup, host, options,
1360
1395
if ( ! self . connecting ) {
1361
1396
return ;
1362
1397
} else if ( err ) {
1398
+ self . emit ( 'lookup' , err , undefined , undefined , host ) ;
1399
+
1363
1400
// net.createConnection() creates a net.Socket object and immediately
1364
1401
// calls net.Socket.connect() on it (that's us). There are no event
1365
1402
// listeners registered yet so defer the error event to the next tick.
@@ -1559,7 +1596,7 @@ function afterConnectMultiple(context, current, status, handle, req, readable, w
1559
1596
ArrayPrototypePush ( context . errors , ex ) ;
1560
1597
1561
1598
// Try the next address
1562
- internalConnectMultiple ( context ) ;
1599
+ internalConnectMultiple ( context , status === UV_ECANCELED ) ;
1563
1600
return ;
1564
1601
}
1565
1602
@@ -1570,13 +1607,9 @@ function afterConnectMultiple(context, current, status, handle, req, readable, w
1570
1607
return ;
1571
1608
}
1572
1609
1573
- // Perform initialization sequence on the handle, then move on with the regular callback
1574
- self . _handle = handle ;
1575
- initSocketHandle ( self ) ;
1576
-
1577
- if ( self [ kWrapConnectedHandle ] ) {
1578
- self [ kWrapConnectedHandle ] ( handle ) ;
1579
- initSocketHandle ( self ) ; // This is called again to initialize the TLSWrap
1610
+ if ( context . current > 1 && self [ kReinitializeHandle ] ) {
1611
+ self [ kReinitializeHandle ] ( handle ) ;
1612
+ handle = self . _handle ;
1580
1613
}
1581
1614
1582
1615
if ( hasObserver ( 'net' ) ) {
@@ -2295,4 +2328,6 @@ module.exports = {
2295
2328
Stream : Socket , // Legacy naming
2296
2329
getDefaultAutoSelectFamily,
2297
2330
setDefaultAutoSelectFamily,
2331
+ getDefaultAutoSelectFamilyAttemptTimeout,
2332
+ setDefaultAutoSelectFamilyAttemptTimeout,
2298
2333
} ;
0 commit comments