Пример #1
0
    // 1 個の Ping テストを実行する
    async Task <bool> PerformSinglePingTestAsync(InternetCheckerPingTestItem ping, CancellationToken cancel = default)
    {
        SendPingReply reply = await this.TcpIp.SendPingAsync(ping.IpAddress, pingTimeout : Options.PingTimeout, pingCancel : cancel, dnsCancel : cancel);

        return(reply.Ok);
    }
Пример #2
0
    protected override async Task GetValueAsync(SortedDictionary <string, string> ret, RefInt nextPollingInterval, CancellationToken cancel = default)
    {
        SnmpWorkSettings settings = Host.Settings;

        if (settings.PingTargets._IsSamei("none") || settings.PingTargets._IsSamei("null"))
        {
            return;
        }

        string hopsStr = "Hops";

        if (settings.HopsToTTL)
        {
            hopsStr = "TTL";
        }

        string[] pingTargets = settings.PingTargets._Split(StringSplitOptions.RemoveEmptyEntries, ",");

        numPerform++;

        foreach (string pingTarget in pingTargets)
        {
            cancel.ThrowIfCancellationRequested();

            ParseTargetString(pingTarget, out string hostname, out string alias);

            bool ok = false;

            try
            {
                IPAddress ipAddress = await LocalNet.GetIpAsync(hostname, cancel : cancel);

                if (FirstPing.IsFirstCall())
                {
                    // JIT 対策
                    try
                    {
                        await LocalNet.SendPingAsync(ipAddress, pingCancel : cancel);
                    }
                    catch { }
                }

                int numTry = 3;

                if (numPerform >= 2)
                {
                    // SpeedTest が動作中の場合は SpeedTest が完了するまで待機する
                    await TaskUtil.AwaitWithPollAsync(Timeout.Infinite, 10, () => !SpeedTestClient.IsInProgress, cancel);

                    // 試行回数を指定する
                    numTry = Math.Min(Math.Max(settings.PingNumTry, 1), 100);
                }

                SendPingReply reply = await LocalNet.SendPingAndGetBestResultAsync(ipAddress, pingCancel : cancel, numTry : numTry);

                if (reply.Ok)
                {
                    double rtt = reply.RttDouble;

                    rtt = Math.Min(rtt, 2.0);

                    int ttl = reply.Ttl;

                    bool ttl_ok = false;

                    if (ttl == 0)
                    {
                        // Use ping command to get TTL
                        try
                        {
                            var result = await EasyExec.ExecAsync(ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6?Consts.LinuxCommands.Ping6 : Consts.LinuxCommands.Ping,
                                                                  $"-W 1 -c 1 {ipAddress.ToString()}",
                                                                  cancel : cancel,
                                                                  throwOnErrorExitCode : false);

                            string[] lines = result.OutputStr._GetLines(true);

                            foreach (string line in lines)
                            {
                                OneLineParams param  = new OneLineParams(line, ' ', false);
                                string        ttlStr = param._GetStrFirst("ttl");
                                if (ttlStr._IsFilled())
                                {
                                    ttl    = ttlStr._ToInt();
                                    ttl_ok = true;
                                    break;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            ex._Debug();
                        }
                    }
                    else
                    {
                        ttl_ok = true;
                    }

                    ret.TryAdd($"Time - {alias}", (rtt * 1000.0).ToString("F3"));


                    if (ttl > 128)
                    {
                        ttl -= 128;
                    }
                    else if (ttl > 64)
                    {
                        ttl -= 64;
                    }

                    int hops = 64 - ttl;

                    if (ttl_ok == false)
                    {
                        hops = 0;
                    }

                    hops._SetMax(0);
                    hops._SetMin(64);

                    ret.TryAdd($"{hopsStr} - {alias}", hops.ToString());

                    ok = true;
                }
            }
            catch (Exception ex)
            {
                ex._Debug();
            }

            if (ok == false)
            {
                ret.TryAdd($"Time - {alias}", "");
                ret.TryAdd($"{hopsStr} - {alias}", "0");
            }
        }
    }
Пример #3
0
    // 実行スレッド
    void pingerThreadProc(object?param)
    {
        string optionsStr = this.DefaultOptions; // まずデフォルトのオプション文字列を読む

        string hostname = TargetHost;

        if (hostname._InStri("@"))
        {
            if (hostname._GetKeyAndValue(out string hostname2, out string tmp, "@"))
            {
                hostname = hostname2;

                // オプション文字列が個別に指定されていた場合は、それを先に付ける。同じ項目について上書きをすることになる、
                optionsStr = tmp._NonNull() + "," + optionsStr;
            }
        }

        // オプション文字列のパース
        var options = QueryStringList.Parse(optionsStr, splitChar: ',', trimKeyAndValue: true);

        // IP アドレスバージョンの決定
        AllowedIPVersions allowedIPVersions = AllowedIPVersions.All;

        string ipVerStr = options._GetStrFirst("ipver");

        if (ipVerStr._InStr("4") && ipVerStr._InStr("6") == false)
        {
            allowedIPVersions = AllowedIPVersions.IPv4;
        }
        else if (ipVerStr._InStr("6") && ipVerStr._InStr("4") == false)
        {
            allowedIPVersions = AllowedIPVersions.IPv6;
        }

        bool preferV6 = false;

        string ipperfer = options._GetStrFirst("ipprefer");

        if (ipperfer._InStri("6"))
        {
            preferV6 = true;
        }

        IPAddress GetIpAddress(string hostname, AllowedIPVersions allowedIPVersions)
        {
            var ip = hostname._ToIPAddress(allowedIPVersions, true);

            if (ip != null)
            {
                return(ip);
            }

            return(this.DnsClient.GetIpAddressAsync(hostname, allowedIPVersions, preferV6, noCache: true)._GetResult());
        }

        if (TargetPort == 0)
        {
            // ping の実行
            try
            {
                IPAddress ip = GetIpAddress(hostname, allowedIPVersions);

                SendPingReply ret = SendPing.Send(ip, null, Timeout);

                lock (lockObj)
                {
                    ok       = ret.Ok;
                    finished = true;
                }
            }
            catch
            {
                lock (lockObj)
                {
                    ok       = false;
                    finished = true;
                }
            }

            Console.Write(ok ? "+" : "-");
        }
        else
        {
            int  port      = TargetPort;
            bool tcp_check = false;

            if (port >= 100000)
            {
                port     -= 100000;
                tcp_check = true;
            }

            // TCP Connect の実行
            try
            {
                if (tcp_check == false)
                {
                    IPAddress ip = GetIpAddress(hostname, allowedIPVersions);

                    Sock s = Sock.Connect(ip.ToString(), port, Timeout, true, true);

                    try
                    {
                        if (TcpSendData)
                        {
                            s.SetTimeout(Timeout);

                            long end_tick    = Time.Tick64 + (long)Timeout;
                            int  num_packets = 0;

                            while (true)
                            {
                                if (Time.Tick64 > end_tick)
                                {
                                    break;
                                }

                                if (num_packets >= 16)
                                {
                                    break;
                                }

                                byte[] data = new byte[1];
                                data[0] = (byte)'a';
                                if (s.SendAll(data) == false)
                                {
                                    break;
                                }

                                ThreadObj.Sleep(1);
                                num_packets++;
                            }
                        }

                        s.Disconnect();
                    }
                    catch
                    {
                    }
                }
                else
                {
                    IPAddress ip = GetIpAddress(hostname, allowedIPVersions);

                    if (tcp_check_do(ip.ToString(), port, Timeout) == false)
                    {
                        throw new ApplicationException();
                    }
                }

                lock (lockObj)
                {
                    ok       = true;
                    finished = true;
                }
            }
            catch
            {
                lock (lockObj)
                {
                    ok       = false;
                    finished = true;
                }
            }

            Console.Write(ok ? "*" : "-");
        }

        //EndEvent.Set();
    }