From 04c1241893dd57d07b0aac014b9bb0cd47b4b4b9 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Thu, 13 Dec 2018 14:10:34 -0800 Subject: [PATCH 1/2] use connect on unicast ping addresses to avoild processing incorrect responses --- .../System/Net/NetworkInformation/Ping.Unix.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs b/src/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs index 01fe0d2be926..27c158058a30 100644 --- a/src/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs +++ b/src/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs @@ -88,8 +88,10 @@ private SocketConfig GetSocketConfig(IPAddress address, byte[] buffer, int timeo private Socket GetRawSocket(SocketConfig socketConfig) { + IPEndPoint ep = socketConfig.EndPoint as IPEndPoint; + // Setting Socket.DontFragment and .Ttl is not supported on Unix, so socketConfig.Options is ignored. - AddressFamily addrFamily = ((IPEndPoint)socketConfig.EndPoint).Address.AddressFamily; + AddressFamily addrFamily = ep.Address.AddressFamily; Socket socket = new Socket(addrFamily, SocketType.Raw, socketConfig.ProtocolType); socket.ReceiveTimeout = socketConfig.Timeout; socket.SendTimeout = socketConfig.Timeout; @@ -97,6 +99,16 @@ private Socket GetRawSocket(SocketConfig socketConfig) { socket.Ttl = (short)socketConfig.Options.Ttl; } + +#pragma warning disable 618 + // Disable warning about obsolete property. We could use GetAddressBytes but that allocates. + if (!ep.Address.IsIPv6Multicast && !(addrFamily == AddressFamily.InterNetwork && (ep.Address.Address & 0xf0) == 0xe0)) + { + // If it is not multicast, use Connect to scope responses only tho target address. + socket.Connect(socketConfig.EndPoint); + } +#pragma warning restore 618 + return socket; } @@ -129,7 +141,7 @@ private bool TryGetPingReply(SocketConfig socketConfig, byte[] receiveBuffer, in { return false; } - + sw.Stop(); long roundTripTime = sw.ElapsedMilliseconds; int dataOffset = ipHeaderLength + IcmpHeaderLengthInBytes; From f90312733b8ba846ed448f19b88b2a096ff2f187 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Fri, 14 Dec 2018 14:59:17 -0800 Subject: [PATCH 2/2] feedback from review --- .../src/System/Net/NetworkInformation/Ping.Unix.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs b/src/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs index 27c158058a30..d9f28d0754d2 100644 --- a/src/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs +++ b/src/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs @@ -88,7 +88,7 @@ private SocketConfig GetSocketConfig(IPAddress address, byte[] buffer, int timeo private Socket GetRawSocket(SocketConfig socketConfig) { - IPEndPoint ep = socketConfig.EndPoint as IPEndPoint; + IPEndPoint ep = (IPEndPoint)socketConfig.EndPoint; // Setting Socket.DontFragment and .Ttl is not supported on Unix, so socketConfig.Options is ignored. AddressFamily addrFamily = ep.Address.AddressFamily; @@ -102,9 +102,10 @@ private Socket GetRawSocket(SocketConfig socketConfig) #pragma warning disable 618 // Disable warning about obsolete property. We could use GetAddressBytes but that allocates. + // IPv4 multicast address starts with 1110 bits so mask rest and test if we get correct value e.g. 0xe0. if (!ep.Address.IsIPv6Multicast && !(addrFamily == AddressFamily.InterNetwork && (ep.Address.Address & 0xf0) == 0xe0)) { - // If it is not multicast, use Connect to scope responses only tho target address. + // If it is not multicast, use Connect to scope responses only to the target address. socket.Connect(socketConfig.EndPoint); } #pragma warning restore 618