Skip to content
This repository has been archived by the owner on Aug 15, 2022. It is now read-only.

Commit

Permalink
Set UDP Client socket to disregard ICMP errors and forcibly disconnect.
Browse files Browse the repository at this point in the history
  • Loading branch information
phalasz committed Aug 28, 2019
1 parent eacb104 commit 2d3aae7
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand All @@ -46,6 +46,19 @@ namespace BeardedManStudios.Forge.Networking
{
public class CachedUdpClient : IDisposable
{
/// <summary>
/// Winsock ioctl code which will disable ICMP errors from being propagated to a UDP socket.
/// This can occur if a UDP packet is sent to a valid destination but there is no socket
/// registered to listen on the given port.
/// </summary>
/// http://msdn.microsoft.com/en-us/library/cc242275.aspx
/// http://msdn.microsoft.com/en-us/library/bb736550(VS.85).aspx
/// https://stackoverflow.com/questions/7201862/an-existing-connection-was-forcibly-closed-by-the-remote-host/7478498#7478498
/// uint IOC_IN = 0x80000000;
/// uint IOC_VENDOR = 0x18000000;
/// uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
private const int SIO_UDP_CONNRESET = -1744830452;

public const char HOST_PORT_CHARACTER_SEPARATOR = '+';
private bool disposed = false;
private bool active = false;
Expand Down Expand Up @@ -143,6 +156,7 @@ private void InitSocket(EndPoint localEP)
recBuffer.SetSize(65536);
}


#region Close
public void Close()
{
Expand Down Expand Up @@ -226,6 +240,17 @@ public void Connect(string hostname, int port)
}
}
}

/// <summary>
/// Enable/disable whether the socket should disregard ICMP Port unreachable errors
/// </summary>
/// <param name="enabled"></param>
public void IgnoreICMPErrors(bool enabled)
{
// set socket to disregard ICMP errors.
socket.IOControl(SIO_UDP_CONNRESET, new byte[] {Convert.ToByte(!enabled)}, null);
}

#endregion
#region Multicast methods
public void DropMulticastGroup(IPAddress multicastAddr)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,14 @@ private void AttemptServerConnection(object _)
// This is a typical Websockets accept header to be validated
byte[] connectHeader = Websockets.ConnectionHeader(headerHash, Port);

Client.IgnoreICMPErrors(true);
do
{
// Send the accept headers to the server to validate
Client.Send(connectHeader, connectHeader.Length, ServerPlayer.IPEndPointHandle);
Thread.Sleep(3000);
} while (!initialConnectHeaderExchanged && IsBound && ++connectCounter < CONNECT_TRIES);
Client.IgnoreICMPErrors(false);

if (connectCounter >= CONNECT_TRIES && connectAttemptFailed != null)
connectAttemptFailed(this);
Expand Down

0 comments on commit 2d3aae7

Please sign in to comment.