Skip to content

Commit 7816766

Browse files
Merge branch 'master' into unify-onmodel
2 parents 33b2a40 + e84d339 commit 7816766

File tree

4 files changed

+35
-9
lines changed

4 files changed

+35
-9
lines changed

projects/RabbitMQ.Client/client/api/ITcpClient.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Net;
23
using System.Net.Sockets;
34
using System.Threading.Tasks;
45

@@ -17,6 +18,7 @@ public interface ITcpClient : IDisposable
1718
Socket Client { get; }
1819

1920
Task ConnectAsync(string host, int port);
21+
Task ConnectAsync(IPAddress host, int port);
2022

2123
NetworkStream GetStream();
2224

projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,21 +101,38 @@ public SocketFrameHandler(AmqpTcpEndpoint endpoint,
101101
_channelReader = channel.Reader;
102102
_channelWriter = channel.Writer;
103103

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))
105116
{
106117
try
107118
{
108-
_socket = ConnectUsingIPv6(endpoint, socketFactory, connectionTimeout);
119+
_socket = ConnectUsingIPv6(new IPEndPoint(ipv6, endpoint.Port), socketFactory, connectionTimeout);
109120
}
110121
catch (ConnectFailureException)
111122
{
123+
// We resolved to a ipv6 address and tried it but it still didn't connect, try IPv4
112124
_socket = null;
113125
}
114126
}
115127

116-
if (_socket == null && endpoint.AddressFamily != AddressFamily.InterNetworkV6)
128+
if (_socket == null)
117129
{
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);
119136
}
120137

121138
Stream netstream = _socket.GetStream();
@@ -276,21 +293,21 @@ private static bool ShouldTryIPv6(AmqpTcpEndpoint endpoint)
276293
return Socket.OSSupportsIPv6 && endpoint.AddressFamily != AddressFamily.InterNetwork;
277294
}
278295

279-
private ITcpClient ConnectUsingIPv6(AmqpTcpEndpoint endpoint,
296+
private ITcpClient ConnectUsingIPv6(IPEndPoint endpoint,
280297
Func<AddressFamily, ITcpClient> socketFactory,
281298
TimeSpan timeout)
282299
{
283300
return ConnectUsingAddressFamily(endpoint, socketFactory, timeout, AddressFamily.InterNetworkV6);
284301
}
285302

286-
private ITcpClient ConnectUsingIPv4(AmqpTcpEndpoint endpoint,
303+
private ITcpClient ConnectUsingIPv4(IPEndPoint endpoint,
287304
Func<AddressFamily, ITcpClient> socketFactory,
288305
TimeSpan timeout)
289306
{
290307
return ConnectUsingAddressFamily(endpoint, socketFactory, timeout, AddressFamily.InterNetwork);
291308
}
292309

293-
private ITcpClient ConnectUsingAddressFamily(AmqpTcpEndpoint endpoint,
310+
private ITcpClient ConnectUsingAddressFamily(IPEndPoint endpoint,
294311
Func<AddressFamily, ITcpClient> socketFactory,
295312
TimeSpan timeout, AddressFamily family)
296313
{
@@ -307,11 +324,11 @@ private ITcpClient ConnectUsingAddressFamily(AmqpTcpEndpoint endpoint,
307324
}
308325
}
309326

310-
private void ConnectOrFail(ITcpClient socket, AmqpTcpEndpoint endpoint, TimeSpan timeout)
327+
private void ConnectOrFail(ITcpClient socket, IPEndPoint endpoint, TimeSpan timeout)
311328
{
312329
try
313330
{
314-
socket.ConnectAsync(endpoint.HostName, endpoint.Port)
331+
socket.ConnectAsync(endpoint.Address, endpoint.Port)
315332
.TimeoutAfter(timeout)
316333
.ConfigureAwait(false)
317334
// this ensures exceptions aren't wrapped in an AggregateException

projects/RabbitMQ.Client/client/impl/TcpClientAdapter.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ public virtual async Task ConnectAsync(string host, int port)
2727
throw new ArgumentException($"No ip address could be resolved for {host}");
2828
}
2929

30+
await ConnectAsync(ep, port);
31+
}
32+
33+
public virtual async Task ConnectAsync(IPAddress ep, int port)
34+
{
35+
AssertSocket();
3036
#if NET461
3137
await Task.Run(() => _sock.Connect(ep, port)).ConfigureAwait(false);
3238
#else

projects/Unit/APIApproval.Approve.verified.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ namespace RabbitMQ.Client
493493
bool Connected { get; }
494494
System.TimeSpan ReceiveTimeout { get; set; }
495495
void Close();
496+
System.Threading.Tasks.Task ConnectAsync(System.Net.IPAddress host, int port);
496497
System.Threading.Tasks.Task ConnectAsync(string host, int port);
497498
System.Net.Sockets.NetworkStream GetStream();
498499
}

0 commit comments

Comments
 (0)