Skip to content

Commit 9dc9388

Browse files
authored
fix(1640): don't crash on dns failure (AscensionGameDev#2013)
1 parent 50be564 commit 9dc9388

File tree

3 files changed

+77
-32
lines changed

3 files changed

+77
-32
lines changed

Intersect.Client/Interface/Interface.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
using System.Collections.Generic;
2-
using System.Linq;
3-
41
using Intersect.Client.Core;
5-
using Intersect.Client.Framework.File_Management;
62
using Intersect.Client.Framework.GenericClasses;
73
using Intersect.Client.Framework.Graphics;
84
using Intersect.Client.Framework.Gwen.Control;
@@ -22,8 +18,12 @@ namespace Intersect.Client.Interface
2218
public static partial class Interface
2319
{
2420

25-
public static readonly List<KeyValuePair<string, string>> MsgboxErrors =
26-
new List<KeyValuePair<string, string>>();
21+
public static readonly List<KeyValuePair<string, string>> MsgboxErrors = new();
22+
23+
public static void ShowError(string message, string? header = default)
24+
{
25+
MsgboxErrors.Add(new KeyValuePair<string, string>(header ?? string.Empty, message));
26+
}
2727

2828
public static ErrorHandler ErrorMsgHandler;
2929

Intersect.Client/Localization/Strings.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Globalization;
4-
using System.IO;
5-
using System.Linq;
61
using System.Reflection;
72
using Intersect.Configuration;
83
using Intersect.Enums;
@@ -917,6 +912,9 @@ public partial struct Errors
917912
public static LocalizedString lostconnection =
918913
@"Lost connection to the game server. Please make sure you're connected to the internet and try again!";
919914

915+
public static LocalizedString HostNotFound =
916+
@"DNS resolution error, please report this to the game administrator.";
917+
920918
}
921919

922920
public partial struct Words

Intersect.Client/MonoGame/Network/MonoSocket.cs

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections.Concurrent;
22
using System.Diagnostics.CodeAnalysis;
33
using System.Net;
4+
using System.Net.Sockets;
45
using System.Resources;
56
using Intersect.Client.Framework.Network;
67
using Intersect.Configuration;
@@ -11,6 +12,7 @@
1112
using Intersect.Client.Core;
1213
using Intersect.Client.General;
1314
using Intersect.Client.Interface.Menu;
15+
using Intersect.Client.Localization;
1416
using Intersect.Network.Packets.Unconnected.Client;
1517
using Intersect.Rsa;
1618

@@ -94,6 +96,7 @@ public INetwork? Network
9496
private string? _lastHost;
9597
private int? _lastPort;
9698
private IPEndPoint? _lastEndpoint;
99+
private static HashSet<string> UnresolvableHostNames = new();
97100

98101
internal MonoSocket(IClientContext context)
99102
{
@@ -103,6 +106,12 @@ internal MonoSocket(IClientContext context)
103106
private bool TryResolveEndPoint([NotNullWhen(true)] out IPEndPoint? endPoint)
104107
{
105108
var currentHost = ClientConfiguration.Instance.Host;
109+
if (UnresolvableHostNames.Contains(currentHost))
110+
{
111+
endPoint = default;
112+
return false;
113+
}
114+
106115
if (!string.Equals(_lastHost, currentHost))
107116
{
108117
_lastHost = currentHost;
@@ -128,17 +137,33 @@ private bool TryResolveEndPoint([NotNullWhen(true)] out IPEndPoint? endPoint)
128137
return true;
129138
}
130139

131-
var address = Dns.GetHostAddresses(_lastHost).FirstOrDefault();
132-
var port = _lastPort;
133-
if (address == default || !port.HasValue)
140+
try
141+
{
142+
var address = Dns.GetHostAddresses(_lastHost).FirstOrDefault();
143+
var port = _lastPort;
144+
if (address == default || !port.HasValue)
145+
{
146+
endPoint = default;
147+
return false;
148+
}
149+
150+
endPoint = new IPEndPoint(address, port.Value);
151+
_lastEndpoint = endPoint;
152+
return true;
153+
}
154+
catch (SocketException socketException)
134155
{
156+
if (socketException.SocketErrorCode != SocketError.HostNotFound)
157+
{
158+
throw;
159+
}
160+
161+
UnresolvableHostNames.Add(_lastHost);
162+
Interface.Interface.ShowError(Strings.Errors.HostNotFound);
163+
Log.Error(socketException, $"Failed to resolve host: '{_lastHost}'");
135164
endPoint = default;
136165
return false;
137166
}
138-
139-
endPoint = new IPEndPoint(address, port.Value);
140-
_lastEndpoint = endPoint;
141-
return true;
142167
}
143168

144169
public override void Connect(string host, int port)
@@ -178,6 +203,10 @@ public static bool AddPacketToQueue(IConnection connection, IPacket packet)
178203
return true;
179204
}
180205

206+
private volatile bool _resolvingHost;
207+
208+
209+
181210
public override void Update()
182211
{
183212
while (PacketQueue.TryDequeue(out KeyValuePair<IConnection, IPacket> dequeued))
@@ -192,21 +221,39 @@ public override void Update()
192221
// ReSharper disable once InvertIf
193222
if (_nextServerStatusPing <= now)
194223
{
195-
if (TryResolveEndPoint(out var serverEndpoint))
196-
{
197-
var network = Network;
198-
if (network == default)
199-
{
200-
Log.Info("No network created to poll for server status.");
201-
}
202-
else
203-
{
204-
network.SendUnconnected(serverEndpoint, new ServerStatusRequestPacket());
205-
}
206-
}
207-
else
224+
if (!_resolvingHost)
208225
{
209-
Log.Info($"Unable to resolve '{_lastHost}:{_lastPort}'");
226+
_resolvingHost = true;
227+
Task.Run(
228+
() =>
229+
{
230+
try
231+
{
232+
if (TryResolveEndPoint(out var serverEndpoint))
233+
{
234+
var network = Network;
235+
if (network == default)
236+
{
237+
Log.Info("No network created to poll for server status.");
238+
}
239+
else
240+
{
241+
network.SendUnconnected(serverEndpoint, new ServerStatusRequestPacket());
242+
}
243+
}
244+
else if (!UnresolvableHostNames.Contains(_lastHost))
245+
{
246+
Log.Info($"Unable to resolve '{_lastHost}:{_lastPort}'");
247+
}
248+
}
249+
catch (Exception exception)
250+
{
251+
Log.Error(exception);
252+
}
253+
254+
_resolvingHost = false;
255+
}
256+
);
210257
}
211258

212259
if (MainMenu.LastNetworkStatusChangeTime + ServerStatusPingInterval < now)

0 commit comments

Comments
 (0)