@@ -101,21 +101,38 @@ public SocketFrameHandler(AmqpTcpEndpoint endpoint,
101
101
_channelReader = channel . Reader ;
102
102
_channelWriter = channel . Writer ;
103
103
104
- if ( ShouldTryIPv6 ( endpoint ) )
104
+ // Resolve the hostname to know if it's even possible to even try IPv6
105
+ IPAddress [ ] adds = Dns . GetHostAddresses ( endpoint . HostName ) ;
106
+ IPAddress ipv6 = TcpClientAdapterHelper . GetMatchingHost ( adds , AddressFamily . InterNetworkV6 ) ;
107
+
108
+ if ( ipv6 == default ( IPAddress ) )
109
+ {
110
+ if ( endpoint . AddressFamily == AddressFamily . InterNetworkV6 )
111
+ {
112
+ throw new ConnectFailureException ( "Connection failed" , new ArgumentException ( $ "No IPv6 address could be resolved for { endpoint . HostName } ") ) ;
113
+ }
114
+ }
115
+ else if ( ShouldTryIPv6 ( endpoint ) )
105
116
{
106
117
try
107
118
{
108
- _socket = ConnectUsingIPv6 ( endpoint , socketFactory , connectionTimeout ) ;
119
+ _socket = ConnectUsingIPv6 ( new IPEndPoint ( ipv6 , endpoint . Port ) , socketFactory , connectionTimeout ) ;
109
120
}
110
121
catch ( ConnectFailureException )
111
122
{
123
+ // We resolved to a ipv6 address and tried it but it still didn't connect, try IPv4
112
124
_socket = null ;
113
125
}
114
126
}
115
127
116
- if ( _socket == null && endpoint . AddressFamily != AddressFamily . InterNetworkV6 )
128
+ if ( _socket == null )
117
129
{
118
- _socket = ConnectUsingIPv4 ( endpoint , socketFactory , connectionTimeout ) ;
130
+ IPAddress ipv4 = TcpClientAdapterHelper . GetMatchingHost ( adds , AddressFamily . InterNetwork ) ;
131
+ if ( ipv4 == default ( IPAddress ) )
132
+ {
133
+ throw new ConnectFailureException ( "Connection failed" , new ArgumentException ( $ "No ip address could be resolved for { endpoint . HostName } ") ) ;
134
+ }
135
+ _socket = ConnectUsingIPv4 ( new IPEndPoint ( ipv4 , endpoint . Port ) , socketFactory , connectionTimeout ) ;
119
136
}
120
137
121
138
Stream netstream = _socket . GetStream ( ) ;
@@ -276,21 +293,21 @@ private static bool ShouldTryIPv6(AmqpTcpEndpoint endpoint)
276
293
return Socket . OSSupportsIPv6 && endpoint . AddressFamily != AddressFamily . InterNetwork ;
277
294
}
278
295
279
- private ITcpClient ConnectUsingIPv6 ( AmqpTcpEndpoint endpoint ,
296
+ private ITcpClient ConnectUsingIPv6 ( IPEndPoint endpoint ,
280
297
Func < AddressFamily , ITcpClient > socketFactory ,
281
298
TimeSpan timeout )
282
299
{
283
300
return ConnectUsingAddressFamily ( endpoint , socketFactory , timeout , AddressFamily . InterNetworkV6 ) ;
284
301
}
285
302
286
- private ITcpClient ConnectUsingIPv4 ( AmqpTcpEndpoint endpoint ,
303
+ private ITcpClient ConnectUsingIPv4 ( IPEndPoint endpoint ,
287
304
Func < AddressFamily , ITcpClient > socketFactory ,
288
305
TimeSpan timeout )
289
306
{
290
307
return ConnectUsingAddressFamily ( endpoint , socketFactory , timeout , AddressFamily . InterNetwork ) ;
291
308
}
292
309
293
- private ITcpClient ConnectUsingAddressFamily ( AmqpTcpEndpoint endpoint ,
310
+ private ITcpClient ConnectUsingAddressFamily ( IPEndPoint endpoint ,
294
311
Func < AddressFamily , ITcpClient > socketFactory ,
295
312
TimeSpan timeout , AddressFamily family )
296
313
{
@@ -307,11 +324,11 @@ private ITcpClient ConnectUsingAddressFamily(AmqpTcpEndpoint endpoint,
307
324
}
308
325
}
309
326
310
- private void ConnectOrFail ( ITcpClient socket , AmqpTcpEndpoint endpoint , TimeSpan timeout )
327
+ private void ConnectOrFail ( ITcpClient socket , IPEndPoint endpoint , TimeSpan timeout )
311
328
{
312
329
try
313
330
{
314
- socket . ConnectAsync ( endpoint . HostName , endpoint . Port )
331
+ socket . ConnectAsync ( endpoint . Address , endpoint . Port )
315
332
. TimeoutAfter ( timeout )
316
333
. ConfigureAwait ( false )
317
334
// this ensures exceptions aren't wrapped in an AggregateException
0 commit comments