// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
internal byte optionsSize;
internal IntPtr optionsData;
- internal IPOptions(PingOptions options)
+ internal IPOptions(PingOptions? options)
{
ttl = 128;
tos = 0;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
private const string s_ipv4PingFile = "ping";
private const string s_ipv6PingFile = "ping6";
- private static readonly string s_discoveredPing4UtilityPath = GetPingUtilityPath(ipv4: true);
- private static readonly string s_discoveredPing6UtilityPath = GetPingUtilityPath(ipv4: false);
+ private static readonly string? s_discoveredPing4UtilityPath = GetPingUtilityPath(ipv4: true);
+ private static readonly string? s_discoveredPing6UtilityPath = GetPingUtilityPath(ipv4: false);
private static readonly bool s_isBSD = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD"));
private static readonly Lazy<bool> s_isBusybox = new Lazy<bool>(() => IsBusyboxPing(s_discoveredPing4UtilityPath));
// We don't want to pick up an arbitrary or malicious ping
// command, so that's why we do the path probing ourselves.
- private static string GetPingUtilityPath(bool ipv4)
+ private static string? GetPingUtilityPath(bool ipv4)
{
string fileName = ipv4 ? s_ipv4PingFile : s_ipv6PingFile;
foreach (string folder in s_binFolders)
}
// Check if found ping is symlink to busybox like alpine /bin/ping -> /bin/busybox
- private static unsafe bool IsBusyboxPing(string pingBinary)
+ private static unsafe bool IsBusyboxPing(string? pingBinary)
{
- string linkedName = Interop.Sys.ReadLink(pingBinary);
-
- // If pingBinary is not link linkedName will be null
- if (linkedName != null && linkedName.EndsWith("busybox", StringComparison.Ordinal))
+ if (pingBinary != null)
{
- return true;
+ string? linkedName = Interop.Sys.ReadLink(pingBinary);
+
+ // If pingBinary is not link linkedName will be null
+ if (linkedName != null && linkedName.EndsWith("busybox", StringComparison.Ordinal))
+ {
+ return true;
+ }
}
return false;
/// <summary>
/// The location of the IPv4 ping utility on the current machine.
/// </summary>
- public static string Ping4UtilityPath { get { return s_discoveredPing4UtilityPath; } }
+ public static string? Ping4UtilityPath { get { return s_discoveredPing4UtilityPath; } }
/// <summary>
/// The location of the IPv6 ping utility on the current machine.
/// </summary>
- public static string Ping6UtilityPath { get { return s_discoveredPing6UtilityPath; } }
+ public static string? Ping6UtilityPath { get { return s_discoveredPing6UtilityPath; } }
/// <summary>
/// Constructs command line arguments appropriate for the ping or ping6 utility.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
using System.Globalization;
using System.Net.Sockets;
return Buffer.Length - IntPtr.Size;
}
- public override bool Equals(object comparand)
+ public override bool Equals(object? comparand)
{
- SocketAddress castedComparand = comparand as SocketAddress;
+ SocketAddress? castedComparand = comparand as SocketAddress;
if (castedComparand == null || this.Size != castedComparand.Size)
{
return false;
public partial class Ping : System.ComponentModel.Component
{
public Ping() { }
- public event System.Net.NetworkInformation.PingCompletedEventHandler PingCompleted { add { } remove { } }
+ public event System.Net.NetworkInformation.PingCompletedEventHandler? PingCompleted { add { } remove { } }
protected override void Dispose(bool disposing) { }
protected void OnPingCompleted(System.Net.NetworkInformation.PingCompletedEventArgs e) { }
public System.Net.NetworkInformation.PingReply Send(System.Net.IPAddress address) { throw null; }
public System.Net.NetworkInformation.PingReply Send(System.Net.IPAddress address, int timeout) { throw null; }
public System.Net.NetworkInformation.PingReply Send(System.Net.IPAddress address, int timeout, byte[] buffer) { throw null; }
- public System.Net.NetworkInformation.PingReply Send(System.Net.IPAddress address, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions options) { throw null; }
+ public System.Net.NetworkInformation.PingReply Send(System.Net.IPAddress address, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; }
public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress) { throw null; }
public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout) { throw null; }
public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout, byte[] buffer) { throw null; }
- public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions options) { throw null; }
- public void SendAsync(System.Net.IPAddress address, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions options, object userToken) { }
- public void SendAsync(System.Net.IPAddress address, int timeout, byte[] buffer, object userToken) { }
- public void SendAsync(System.Net.IPAddress address, int timeout, object userToken) { }
- public void SendAsync(System.Net.IPAddress address, object userToken) { }
- public void SendAsync(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions options, object userToken) { }
- public void SendAsync(string hostNameOrAddress, int timeout, byte[] buffer, object userToken) { }
- public void SendAsync(string hostNameOrAddress, int timeout, object userToken) { }
- public void SendAsync(string hostNameOrAddress, object userToken) { }
+ public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; }
+ public void SendAsync(System.Net.IPAddress address, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options, object? userToken) { }
+ public void SendAsync(System.Net.IPAddress address, int timeout, byte[] buffer, object? userToken) { }
+ public void SendAsync(System.Net.IPAddress address, int timeout, object? userToken) { }
+ public void SendAsync(System.Net.IPAddress address, object? userToken) { }
+ public void SendAsync(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options, object? userToken) { }
+ public void SendAsync(string hostNameOrAddress, int timeout, byte[] buffer, object? userToken) { }
+ public void SendAsync(string hostNameOrAddress, int timeout, object? userToken) { }
+ public void SendAsync(string hostNameOrAddress, object? userToken) { }
public void SendAsyncCancel() { }
public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(System.Net.IPAddress address) { throw null; }
public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(System.Net.IPAddress address, int timeout) { throw null; }
public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(System.Net.IPAddress address, int timeout, byte[] buffer) { throw null; }
- public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(System.Net.IPAddress address, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions options) { throw null; }
+ public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(System.Net.IPAddress address, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; }
public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(string hostNameOrAddress) { throw null; }
public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(string hostNameOrAddress, int timeout) { throw null; }
public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(string hostNameOrAddress, int timeout, byte[] buffer) { throw null; }
- public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions options) { throw null; }
+ public System.Threading.Tasks.Task<System.Net.NetworkInformation.PingReply> SendPingAsync(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; }
}
public partial class PingCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
{
public partial class PingException : System.InvalidOperationException
{
protected PingException(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) { }
- public PingException(string message) { }
- public PingException(string message, System.Exception innerException) { }
+ public PingException(string? message) { }
+ public PingException(string? message, System.Exception? innerException) { }
}
public partial class PingOptions
{
internal PingReply() { }
public System.Net.IPAddress Address { get { throw null; } }
public byte[] Buffer { get { throw null; } }
- public System.Net.NetworkInformation.PingOptions Options { get { throw null; } }
+ public System.Net.NetworkInformation.PingOptions? Options { get { throw null; } }
public long RoundtripTime { get { throw null; } }
public System.Net.NetworkInformation.IPStatus Status { get { throw null; } }
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks>
+ <Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Include="System.Net.Ping.cs" />
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<NoWarn>$(NoWarn);CS1573</NoWarn>
<TargetFrameworks>$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix</TargetFrameworks>
+ <Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Include="System\Net\NetworkInformation\IPStatus.cs" />
using System.ComponentModel;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net.Sockets;
using System.Runtime.InteropServices;
private const int MinIpHeaderLengthInBytes = 20;
private const int MaxIpHeaderLengthInBytes = 60;
[ThreadStatic]
- private static Random t_idGenerator;
+ private static Random? t_idGenerator;
- private PingReply SendPingCore(IPAddress address, byte[] buffer, int timeout, PingOptions options)
+ private PingReply SendPingCore(IPAddress address, byte[] buffer, int timeout, PingOptions? options)
{
PingReply reply = RawSocketPermissions.CanUseRawSockets(address.AddressFamily) ?
SendIcmpEchoRequestOverRawSocket(address, buffer, timeout, options) :
return reply;
}
- private async Task<PingReply> SendPingAsyncCore(IPAddress address, byte[] buffer, int timeout, PingOptions options)
+ private async Task<PingReply> SendPingAsyncCore(IPAddress address, byte[] buffer, int timeout, PingOptions? options)
{
Task<PingReply> t = RawSocketPermissions.CanUseRawSockets(address.AddressFamily) ?
SendIcmpEchoRequestOverRawSocketAsync(address, buffer, timeout, options) :
return reply;
}
- private SocketConfig GetSocketConfig(IPAddress address, byte[] buffer, int timeout, PingOptions options)
+ private SocketConfig GetSocketConfig(IPAddress address, byte[] buffer, int timeout, PingOptions? options)
{
- SocketConfig config = new SocketConfig();
- config.EndPoint = new IPEndPoint(address, 0);
- config.Timeout = timeout;
- config.Options = options;
-
- config.IsIpv4 = address.AddressFamily == AddressFamily.InterNetwork;
- config.ProtocolType = config.IsIpv4 ? ProtocolType.Icmp : ProtocolType.IcmpV6;
-
// Use a random value as the identifier. This doesn't need to be perfectly random
// or very unpredictable, rather just good enough to avoid unexpected conflicts.
- Random rand = t_idGenerator ?? (t_idGenerator = new Random());
- config.Identifier = (ushort)rand.Next((int)ushort.MaxValue + 1);
+ Random rand = t_idGenerator ??= new Random();
+ ushort id = (ushort)rand.Next(ushort.MaxValue + 1);
- IcmpHeader header = new IcmpHeader()
- {
- Type = config.IsIpv4 ? (byte)IcmpV4MessageType.EchoRequest : (byte)IcmpV6MessageType.EchoRequest,
- Code = 0,
- HeaderChecksum = 0,
- Identifier = config.Identifier,
- SequenceNumber = 0,
- };
-
- config.SendBuffer = CreateSendMessageBuffer(header, buffer);
- return config;
+ bool ipv4 = address.AddressFamily == AddressFamily.InterNetwork;
+
+ return new SocketConfig(
+ new IPEndPoint(address, 0), timeout, options,
+ ipv4, ipv4 ? ProtocolType.Icmp : ProtocolType.IcmpV6, id,
+ CreateSendMessageBuffer(new IcmpHeader()
+ {
+ Type = ipv4 ? (byte)IcmpV4MessageType.EchoRequest : (byte)IcmpV6MessageType.EchoRequest,
+ Identifier = id,
+ }, buffer));
}
private Socket GetRawSocket(SocketConfig socketConfig)
return socket;
}
- private bool TryGetPingReply(SocketConfig socketConfig, byte[] receiveBuffer, int bytesReceived, Stopwatch sw, ref int ipHeaderLength, out PingReply reply)
+ private bool TryGetPingReply(
+ SocketConfig socketConfig, byte[] receiveBuffer, int bytesReceived, Stopwatch sw, ref int ipHeaderLength,
+ [NotNullWhen(true)] out PingReply? reply)
{
byte type, code;
reply = null;
return true;
}
- private PingReply SendIcmpEchoRequestOverRawSocket(IPAddress address, byte[] buffer, int timeout, PingOptions options)
+ private PingReply SendIcmpEchoRequestOverRawSocket(IPAddress address, byte[] buffer, int timeout, PingOptions? options)
{
SocketConfig socketConfig = GetSocketConfig(address, buffer, timeout, options);
using (Socket socket = GetRawSocket(socketConfig))
continue; // Not enough bytes to reconstruct IP header + ICMP header.
}
- if (TryGetPingReply(socketConfig, receiveBuffer, bytesReceived, sw, ref ipHeaderLength, out PingReply reply))
+ if (TryGetPingReply(socketConfig, receiveBuffer, bytesReceived, sw, ref ipHeaderLength, out PingReply? reply))
{
return reply;
}
}
}
- private async Task<PingReply> SendIcmpEchoRequestOverRawSocketAsync(IPAddress address, byte[] buffer, int timeout, PingOptions options)
+ private async Task<PingReply> SendIcmpEchoRequestOverRawSocketAsync(IPAddress address, byte[] buffer, int timeout, PingOptions? options)
{
SocketConfig socketConfig = GetSocketConfig(address, buffer, timeout, options);
using (Socket socket = GetRawSocket(socketConfig))
continue; // Not enough bytes to reconstruct IP header + ICMP header.
}
- if (TryGetPingReply(socketConfig, receiveBuffer, bytesReceived, sw, ref ipHeaderLength, out PingReply reply))
+ if (TryGetPingReply(socketConfig, receiveBuffer, bytesReceived, sw, ref ipHeaderLength, out PingReply? reply))
{
return reply;
}
}
}
- private Process GetPingProcess(IPAddress address, byte[] buffer, PingOptions options)
+ private Process GetPingProcess(IPAddress address, byte[] buffer, PingOptions? options)
{
bool isIpv4 = address.AddressFamily == AddressFamily.InterNetwork;
- string pingExecutable = isIpv4 ? UnixCommandLinePing.Ping4UtilityPath : UnixCommandLinePing.Ping6UtilityPath;
+ string? pingExecutable = isIpv4 ? UnixCommandLinePing.Ping4UtilityPath : UnixCommandLinePing.Ping6UtilityPath;
if (pingExecutable == null)
{
throw new PlatformNotSupportedException(SR.net_ping_utility_not_found);
return new Process() { StartInfo = psi };
}
- private PingReply SendWithPingUtility(IPAddress address, byte[] buffer, int timeout, PingOptions options)
+ private PingReply SendWithPingUtility(IPAddress address, byte[] buffer, int timeout, PingOptions? options)
{
using (Process p = GetPingProcess(address, buffer, options))
{
}
}
- private async Task<PingReply> SendWithPingUtilityAsync(IPAddress address, byte[] buffer, int timeout, PingOptions options)
+ private async Task<PingReply> SendWithPingUtilityAsync(IPAddress address, byte[] buffer, int timeout, PingOptions? options)
{
using (Process p = GetPingProcess(address, buffer, options))
{
// and no validation is performed.
private class SocketConfig
{
+ public SocketConfig(EndPoint endPoint, int timeout, PingOptions? options, bool isIPv4, ProtocolType protocolType, ushort id, byte[] sendBuffer)
+ {
+ EndPoint = endPoint;
+ Timeout = timeout;
+ Options = options;
+ IsIpv4 = isIPv4;
+ ProtocolType = protocolType;
+ Identifier = id;
+ SendBuffer = sendBuffer;
+ }
+
public EndPoint EndPoint;
- public PingOptions Options;
- public ushort Identifier;
- public bool IsIpv4;
- public ProtocolType ProtocolType;
- public int Timeout;
- public byte[] SendBuffer;
+ public readonly int Timeout;
+ public readonly PingOptions? Options;
+ public readonly ushort Identifier;
+ public readonly bool IsIpv4;
+ public readonly ProtocolType ProtocolType;
+ public readonly byte[] SendBuffer;
}
private static unsafe byte[] CreateSendMessageBuffer(IcmpHeader header, byte[] payload)
private int _sendSize = 0; // Needed to determine what the reply size is for ipv6 in callback.
private bool _ipv6 = false;
- private ManualResetEvent _pingEvent;
- private RegisteredWaitHandle _registeredWait;
- private SafeLocalAllocHandle _requestBuffer;
- private SafeLocalAllocHandle _replyBuffer;
- private Interop.IpHlpApi.SafeCloseIcmpHandle _handlePingV4;
- private Interop.IpHlpApi.SafeCloseIcmpHandle _handlePingV6;
- private TaskCompletionSource<PingReply> _taskCompletionSource;
-
- private PingReply SendPingCore(IPAddress address, byte[] buffer, int timeout, PingOptions options)
+ private ManualResetEvent? _pingEvent;
+ private RegisteredWaitHandle? _registeredWait;
+ private SafeLocalAllocHandle? _requestBuffer;
+ private SafeLocalAllocHandle? _replyBuffer;
+ private Interop.IpHlpApi.SafeCloseIcmpHandle? _handlePingV4;
+ private Interop.IpHlpApi.SafeCloseIcmpHandle? _handlePingV6;
+ private TaskCompletionSource<PingReply>? _taskCompletionSource;
+
+ private PingReply SendPingCore(IPAddress address, byte[] buffer, int timeout, PingOptions? options)
{
// Since isAsync == false, DoSendPingCore will execute synchronously and return a completed
// Task - so no blocking here
return DoSendPingCore(address, buffer, timeout, options, isAsync: false).GetAwaiter().GetResult();
}
- private Task<PingReply> SendPingAsyncCore(IPAddress address, byte[] buffer, int timeout, PingOptions options)
+ private Task<PingReply> SendPingAsyncCore(IPAddress address, byte[] buffer, int timeout, PingOptions? options)
{
// Since isAsync == true, DoSendPingCore will execute asynchronously and return an active Task
return DoSendPingCore(address, buffer, timeout, options, isAsync: true);
// Any exceptions that escape synchronously will be caught by the caller and wrapped in a PingException.
// We do not need to or want to capture such exceptions into the returned task.
- private Task<PingReply> DoSendPingCore(IPAddress address, byte[] buffer, int timeout, PingOptions options, bool isAsync)
+ private Task<PingReply> DoSendPingCore(IPAddress address, byte[] buffer, int timeout, PingOptions? options, bool isAsync)
{
- TaskCompletionSource<PingReply> tcs = null;
+ TaskCompletionSource<PingReply>? tcs = null;
if (isAsync)
{
_taskCompletionSource = tcs = new TaskCompletionSource<PingReply>();
}
}
- if (isAsync)
+ if (tcs != null)
+ {
return tcs.Task;
+ }
Cleanup(isAsync);
return Task.FromResult(CreatePingReply());
_pingEvent.Reset();
}
- _registeredWait = ThreadPool.RegisterWaitForSingleObject(_pingEvent, (state, _) => ((Ping)state).PingCallback(), this, -1, true);
+ _registeredWait = ThreadPool.RegisterWaitForSingleObject(_pingEvent, (state, _) => ((Ping)state!).PingCallback(), this, -1, true);
}
private void UnregisterWaitHandle()
{
if (async)
{
- return _pingEvent.GetSafeWaitHandle();
+ return _pingEvent!.GetSafeWaitHandle();
}
return s_nullSafeWaitHandle;
}
}
- private int SendEcho(IPAddress address, byte[] buffer, int timeout, PingOptions options, bool isAsync)
+ private int SendEcho(IPAddress address, byte[] buffer, int timeout, PingOptions? options, bool isAsync)
{
Interop.IpHlpApi.IPOptions ipOptions = new Interop.IpHlpApi.IPOptions(options);
if (!_ipv6)
{
return (int)Interop.IpHlpApi.IcmpSendEcho2(
- _handlePingV4,
+ _handlePingV4!,
GetWaitHandle(isAsync),
IntPtr.Zero,
IntPtr.Zero,
#pragma warning disable CS0618 // Address is marked obsolete
(uint)address.Address,
#pragma warning restore CS0618
- _requestBuffer,
+ _requestBuffer!,
(ushort)buffer.Length,
ref ipOptions,
- _replyBuffer,
+ _replyBuffer!,
MaxUdpPacket,
(uint)timeout);
}
byte[] sourceAddr = new byte[28];
return (int)Interop.IpHlpApi.Icmp6SendEcho2(
- _handlePingV6,
+ _handlePingV6!,
GetWaitHandle(isAsync),
IntPtr.Zero,
IntPtr.Zero,
sourceAddr,
remoteAddr.Buffer,
- _requestBuffer,
+ _requestBuffer!,
(ushort)buffer.Length,
ref ipOptions,
- _replyBuffer,
+ _replyBuffer!,
MaxUdpPacket,
(uint)timeout);
}
private PingReply CreatePingReply()
{
- SafeLocalAllocHandle buffer = _replyBuffer;
+ SafeLocalAllocHandle buffer = _replyBuffer!;
// Marshals and constructs new reply.
if (_ipv6)
// Private callback invoked when icmpsendecho APIs succeed.
private void PingCallback()
{
- TaskCompletionSource<PingReply> tcs = _taskCompletionSource;
+ TaskCompletionSource<PingReply>? tcs = _taskCompletionSource;
_taskCompletionSource = null;
+ Debug.Assert(tcs != null);
- PingReply reply = null;
- Exception error = null;
+ PingReply? reply = null;
+ Exception? error = null;
bool canceled = false;
try
IPStatus ipStatus = GetStatusFromCode((int)reply.status);
long rtt;
- PingOptions options;
+ PingOptions? options;
byte[] buffer;
if (ipStatus == IPStatus.Success)
}
else
{
- rtt = default(long);
- options = default(PingOptions);
+ rtt = 0;
+ options = null;
buffer = Array.Empty<byte>();
}
}
else
{
- rtt = default(long);
+ rtt = 0;
buffer = Array.Empty<byte>();
}
- return new PingReply(address, default(PingOptions), ipStatus, rtt, buffer);
+ return new PingReply(address, null, ipStatus, rtt, buffer);
}
static partial void InitializeSockets()
private const int MaxBufferSize = 65500; // Artificial constraint due to win32 api limitations.
private readonly ManualResetEventSlim _lockObject = new ManualResetEventSlim(initialState: true); // doubles as the ability to wait on the current operation
- private SendOrPostCallback _onPingCompletedDelegate;
- private bool _disposeRequested = false;
- private byte[] _defaultSendBuffer = null;
+ private SendOrPostCallback? _onPingCompletedDelegate;
+ private bool _disposeRequested;
+ private byte[]? _defaultSendBuffer;
private bool _canceled;
// Thread safety:
}
}
- private void CheckArgs(int timeout, byte[] buffer, PingOptions options)
+ private void CheckArgs(int timeout, byte[] buffer, PingOptions? options)
{
CheckDisposed();
if (buffer == null)
}
}
- private void CheckArgs(IPAddress address, int timeout, byte[] buffer, PingOptions options)
+ private void CheckArgs(IPAddress address, int timeout, byte[] buffer, PingOptions? options)
{
CheckArgs(timeout, buffer, options);
}
}
- public event PingCompletedEventHandler PingCompleted;
+ public event PingCompletedEventHandler? PingCompleted;
protected void OnPingCompleted(PingCompletedEventArgs e)
{
return Send(address, timeout, buffer, null);
}
- public PingReply Send(string hostNameOrAddress, int timeout, byte[] buffer, PingOptions options)
+ public PingReply Send(string hostNameOrAddress, int timeout, byte[] buffer, PingOptions? options)
{
if (string.IsNullOrEmpty(hostNameOrAddress))
{
return GetAddressAndSend(hostNameOrAddress, timeout, buffer, options);
}
- public PingReply Send(IPAddress address, int timeout, byte[] buffer, PingOptions options)
+ public PingReply Send(IPAddress address, int timeout, byte[] buffer, PingOptions? options)
{
CheckArgs(address, timeout, buffer, options);
}
}
- public void SendAsync(string hostNameOrAddress, object userToken)
+ public void SendAsync(string hostNameOrAddress, object? userToken)
{
SendAsync(hostNameOrAddress, DefaultTimeout, DefaultSendBuffer, userToken);
}
- public void SendAsync(string hostNameOrAddress, int timeout, object userToken)
+ public void SendAsync(string hostNameOrAddress, int timeout, object? userToken)
{
SendAsync(hostNameOrAddress, timeout, DefaultSendBuffer, userToken);
}
- public void SendAsync(IPAddress address, object userToken)
+ public void SendAsync(IPAddress address, object? userToken)
{
SendAsync(address, DefaultTimeout, DefaultSendBuffer, userToken);
}
- public void SendAsync(IPAddress address, int timeout, object userToken)
+ public void SendAsync(IPAddress address, int timeout, object? userToken)
{
SendAsync(address, timeout, DefaultSendBuffer, userToken);
}
- public void SendAsync(string hostNameOrAddress, int timeout, byte[] buffer, object userToken)
+ public void SendAsync(string hostNameOrAddress, int timeout, byte[] buffer, object? userToken)
{
SendAsync(hostNameOrAddress, timeout, buffer, null, userToken);
}
- public void SendAsync(IPAddress address, int timeout, byte[] buffer, object userToken)
+ public void SendAsync(IPAddress address, int timeout, byte[] buffer, object? userToken)
{
SendAsync(address, timeout, buffer, null, userToken);
}
- public void SendAsync(string hostNameOrAddress, int timeout, byte[] buffer, PingOptions options, object userToken)
+ public void SendAsync(string hostNameOrAddress, int timeout, byte[] buffer, PingOptions? options, object? userToken)
{
TranslateTaskToEap(userToken, SendPingAsync(hostNameOrAddress, timeout, buffer, options));
}
- public void SendAsync(IPAddress address, int timeout, byte[] buffer, PingOptions options, object userToken)
+ public void SendAsync(IPAddress address, int timeout, byte[] buffer, PingOptions? options, object? userToken)
{
TranslateTaskToEap(userToken, SendPingAsync(address, timeout, buffer, options));
}
- private void TranslateTaskToEap(object userToken, Task<PingReply> pingTask)
+ private void TranslateTaskToEap(object? userToken, Task<PingReply> pingTask)
{
pingTask.ContinueWith((t, state) =>
{
- var asyncOp = (AsyncOperation)state;
+ var asyncOp = (AsyncOperation)state!;
var e = new PingCompletedEventArgs(t.IsCompletedSuccessfully ? t.Result : null, t.Exception, t.IsCanceled, asyncOp.UserSuppliedState);
- SendOrPostCallback callback = _onPingCompletedDelegate ?? (_onPingCompletedDelegate = new SendOrPostCallback(o => { OnPingCompleted((PingCompletedEventArgs)o); }));
+ SendOrPostCallback callback = _onPingCompletedDelegate ?? (_onPingCompletedDelegate = new SendOrPostCallback(o => { OnPingCompleted((PingCompletedEventArgs)o!); }));
asyncOp.PostOperationCompleted(callback, e);
}, AsyncOperationManager.CreateOperation(userToken), CancellationToken.None, TaskContinuationOptions.DenyChildAttach, TaskScheduler.Default);
}
return SendPingAsync(hostNameOrAddress, timeout, buffer, null);
}
- public Task<PingReply> SendPingAsync(IPAddress address, int timeout, byte[] buffer, PingOptions options)
+ public Task<PingReply> SendPingAsync(IPAddress address, int timeout, byte[] buffer, PingOptions? options)
{
CheckArgs(address, timeout, buffer, options);
return SendPingAsyncInternal(address, timeout, buffer, options);
}
- private async Task<PingReply> SendPingAsyncInternal(IPAddress address, int timeout, byte[] buffer, PingOptions options)
+ private async Task<PingReply> SendPingAsyncInternal(IPAddress address, int timeout, byte[] buffer, PingOptions? options)
{
// Need to snapshot the address here, so we're sure that it's not changed between now
// and the operation, and to be sure that IPAddress.ToString() is called and not some override.
}
}
- public Task<PingReply> SendPingAsync(string hostNameOrAddress, int timeout, byte[] buffer, PingOptions options)
+ public Task<PingReply> SendPingAsync(string hostNameOrAddress, int timeout, byte[] buffer, PingOptions? options)
{
if (string.IsNullOrEmpty(hostNameOrAddress))
{
_lockObject.Wait();
}
- private PingReply GetAddressAndSend(string hostNameOrAddress, int timeout, byte[] buffer, PingOptions options)
+ private PingReply GetAddressAndSend(string hostNameOrAddress, int timeout, byte[] buffer, PingOptions? options)
{
CheckStart();
try
}
}
- private async Task<PingReply> GetAddressAndSendAsync(string hostNameOrAddress, int timeout, byte[] buffer, PingOptions options)
+ private async Task<PingReply> GetAddressAndSendAsync(string hostNameOrAddress, int timeout, byte[] buffer, PingOptions? options)
{
CheckStart();
try
public class PingCompletedEventArgs : AsyncCompletedEventArgs
{
- internal PingCompletedEventArgs(PingReply reply, Exception error, bool cancelled, object userToken) : base(error, cancelled, userToken)
+ internal PingCompletedEventArgs(PingReply? reply, Exception? error, bool cancelled, object? userToken) : base(error, cancelled, userToken)
{
Reply = reply;
}
- public PingReply Reply { get; }
+ public PingReply? Reply { get; }
}
}
[System.Runtime.CompilerServices.TypeForwardedFrom("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public class PingException : InvalidOperationException
{
- public PingException(string message) :
+ public PingException(string? message) :
base(message)
{
}
- public PingException(string message, Exception innerException) :
+ public PingException(string? message, Exception? innerException) :
base(message, innerException)
{
}
{
public class PingReply
{
- private readonly IPAddress _address;
- private readonly PingOptions _options;
- private readonly IPStatus _ipStatus;
- private readonly long _rtt;
- private readonly byte[] _buffer;
-
internal PingReply(
IPAddress address,
- PingOptions options,
+ PingOptions? options,
IPStatus ipStatus,
long rtt,
byte[] buffer)
{
- _address = address;
- _options = options;
- _ipStatus = ipStatus;
- _rtt = rtt;
- _buffer = buffer;
+ Address = address;
+ Options = options;
+ Status = ipStatus;
+ RoundtripTime = rtt;
+ Buffer = buffer;
}
- public IPStatus Status { get { return _ipStatus; } }
+ public IPStatus Status { get; }
- public IPAddress Address { get { return _address; } }
+ public IPAddress Address { get; }
- public long RoundtripTime { get { return _rtt; } }
+ public long RoundtripTime { get; }
- public PingOptions Options { get { return _options; } }
+ public PingOptions? Options { get; }
- public byte[] Buffer { get { return _buffer; } }
+ public byte[] Buffer { get; }
}
}