Skip to content

Commit b610d75

Browse files
authored
Fix IP Address Support (#187)
1 parent 332109b commit b610d75

File tree

1 file changed

+56
-33
lines changed

1 file changed

+56
-33
lines changed

Source/HiveMQtt/Client/HiveMQClientSocket.cs

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -104,46 +104,19 @@ internal static bool ValidateServerCertificate(
104104
/// <returns>A boolean representing the success or failure of the operation.</returns>
105105
internal async Task<bool> ConnectSocketAsync()
106106
{
107-
IPAddress? ipAddress = null;
108-
var ipHostInfo = await Dns.GetHostEntryAsync(this.Options.Host).ConfigureAwait(false);
107+
IPEndPoint ipEndPoint;
108+
var ipAddress = await this.LookupHostNameAsync(this.Options.Host).ConfigureAwait(false);
109109

110-
if (ipHostInfo.AddressList.Length == 0)
110+
// Create the IPEndPoint depending on whether it is a host name or IP address.
111+
if (ipAddress == null)
111112
{
112-
throw new HiveMQttClientException("Failed to resolve host");
113-
}
114-
115-
// DNS Address resolution logic. If DNS returns multiple records, how do we handle?
116-
// If we have a single record, we can use that.
117-
// If we have multiple records, we can use the first one with respect to the PreferIPv6 option.
118-
if (ipHostInfo.AddressList.Length == 1)
119-
{
120-
ipAddress = ipHostInfo.AddressList[0];
113+
ipEndPoint = new IPEndPoint(IPAddress.Parse(this.Options.Host), this.Options.Port);
121114
}
122115
else
123116
{
124-
// Loop through each to find a preferred address
125-
foreach (var address in ipHostInfo.AddressList)
126-
{
127-
if (this.Options.PreferIPv6 && address.AddressFamily == AddressFamily.InterNetworkV6)
128-
{
129-
ipAddress = address;
130-
break;
131-
}
132-
133-
if (address.AddressFamily == AddressFamily.InterNetwork)
134-
{
135-
ipAddress = address;
136-
break;
137-
}
138-
}
117+
ipEndPoint = new IPEndPoint(ipAddress, this.Options.Port);
139118
}
140119

141-
// We have multiple address returned, but none of them match the PreferIPv6 option.
142-
// Use the first one whatever it is.
143-
ipAddress ??= ipHostInfo.AddressList[0];
144-
145-
IPEndPoint ipEndPoint = new(ipAddress, this.Options.Port);
146-
147120
this.Socket = new(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
148121

149122
try
@@ -352,4 +325,54 @@ internal async Task CancelBackgroundTasksAsync()
352325
Logger.Error("ConnectionMonitorTask did not complete");
353326
}
354327
}
328+
329+
private async Task<IPAddress?> LookupHostNameAsync(string host)
330+
{
331+
try
332+
{
333+
IPAddress? ipAddress = null;
334+
var ipHostInfo = await Dns.GetHostEntryAsync(host).ConfigureAwait(false);
335+
336+
if (ipHostInfo.AddressList.Length == 0)
337+
{
338+
throw new HiveMQttClientException("Failed to resolve host");
339+
}
340+
341+
// DNS Address resolution logic. If DNS returns multiple records, how do we handle?
342+
// If we have a single record, we can use that.
343+
// If we have multiple records, we can use the first one with respect to the PreferIPv6 option.
344+
if (ipHostInfo.AddressList.Length == 1)
345+
{
346+
ipAddress = ipHostInfo.AddressList[0];
347+
}
348+
else
349+
{
350+
// Loop through each to find a preferred address
351+
foreach (var address in ipHostInfo.AddressList)
352+
{
353+
if (this.Options.PreferIPv6 && address.AddressFamily == AddressFamily.InterNetworkV6)
354+
{
355+
ipAddress = address;
356+
break;
357+
}
358+
359+
if (address.AddressFamily == AddressFamily.InterNetwork)
360+
{
361+
ipAddress = address;
362+
break;
363+
}
364+
}
365+
}
366+
367+
// We have multiple address returned, but none of them match the PreferIPv6 option.
368+
// Use the first one whatever it is.
369+
ipAddress ??= ipHostInfo.AddressList[0];
370+
return ipAddress;
371+
}
372+
catch (SocketException socketException)
373+
{
374+
Logger.Debug(socketException.Message);
375+
return null;
376+
}
377+
}
355378
}

0 commit comments

Comments
 (0)