@@ -65,9 +65,8 @@ public function __construct(LoopInterface $loop, ConnectorInterface $connector,
6565
6666 public function connect ()
6767 {
68- $ timer = null ;
6968 $ that = $ this ;
70- return new Promise \Promise (function ($ resolve , $ reject ) use ($ that, & $ timer ) {
69+ return new Promise \Promise (function ($ resolve , $ reject ) use ($ that ) {
7170 $ lookupResolve = function ($ type ) use ($ that , $ resolve , $ reject ) {
7271 return function (array $ ips ) use ($ that , $ type , $ resolve , $ reject ) {
7372 unset($ that ->resolverPromises [$ type ]);
@@ -83,36 +82,36 @@ public function connect()
8382 };
8483
8584 $ that ->resolverPromises [Message::TYPE_AAAA ] = $ that ->resolve (Message::TYPE_AAAA , $ reject )->then ($ lookupResolve (Message::TYPE_AAAA ));
86- $ that ->resolverPromises [Message::TYPE_A ] = $ that ->resolve (Message::TYPE_A , $ reject )->then (function (array $ ips ) use ($ that, & $ timer ) {
85+ $ that ->resolverPromises [Message::TYPE_A ] = $ that ->resolve (Message::TYPE_A , $ reject )->then (function (array $ ips ) use ($ that ) {
8786 // happy path: IPv6 has resolved already (or could not resolve), continue with IPv4 addresses
8887 if ($ that ->resolved [Message::TYPE_AAAA ] === true || !$ ips ) {
8988 return $ ips ;
9089 }
9190
9291 // Otherwise delay processing IPv4 lookup until short timer passes or IPv6 resolves in the meantime
93- $ deferred = new Promise \Deferred ();
92+ $ deferred = new Promise \Deferred (function () use (&$ ips ) {
93+ // discard all IPv4 addresses if cancelled
94+ $ ips = array ();
95+ });
9496 $ timer = $ that ->loop ->addTimer ($ that ::RESOLUTION_DELAY , function () use ($ deferred , $ ips ) {
9597 $ deferred ->resolve ($ ips );
9698 });
9799
98- $ that ->resolverPromises [Message::TYPE_AAAA ]->then (function () use ($ that , $ timer , $ deferred , $ ips ) {
100+ $ that ->resolverPromises [Message::TYPE_AAAA ]->then (function () use ($ that , $ timer , $ deferred , & $ ips ) {
99101 $ that ->loop ->cancelTimer ($ timer );
100102 $ deferred ->resolve ($ ips );
101103 });
102104
103105 return $ deferred ->promise ();
104106 })->then ($ lookupResolve (Message::TYPE_A ));
105- }, function ($ _ , $ reject ) use ($ that, & $ timer ) {
107+ }, function ($ _ , $ reject ) use ($ that ) {
106108 $ reject (new \RuntimeException (
107109 'Connection to ' . $ that ->uri . ' cancelled ' . (!$ that ->connectionPromises ? ' during DNS lookup ' : '' ) . ' (ECONNABORTED) ' ,
108110 \defined ('SOCKET_ECONNABORTED ' ) ? \SOCKET_ECONNABORTED : 103
109111 ));
110112 $ _ = $ reject = null ;
111113
112114 $ that ->cleanUp ();
113- if ($ timer instanceof TimerInterface) {
114- $ that ->loop ->cancelTimer ($ timer );
115- }
116115 });
117116 }
118117
@@ -247,13 +246,15 @@ public function cleanUp()
247246 // clear list of outstanding IPs to avoid creating new connections
248247 $ this ->connectQueue = array ();
249248
249+ // cancel pending connection attempts
250250 foreach ($ this ->connectionPromises as $ connectionPromise ) {
251251 if ($ connectionPromise instanceof PromiseInterface && \method_exists ($ connectionPromise , 'cancel ' )) {
252252 $ connectionPromise ->cancel ();
253253 }
254254 }
255255
256- foreach ($ this ->resolverPromises as $ resolverPromise ) {
256+ // cancel pending DNS resolution (cancel IPv4 first in case it is awaiting IPv6 resolution delay)
257+ foreach (\array_reverse ($ this ->resolverPromises ) as $ resolverPromise ) {
257258 if ($ resolverPromise instanceof PromiseInterface && \method_exists ($ resolverPromise , 'cancel ' )) {
258259 $ resolverPromise ->cancel ();
259260 }
0 commit comments