public void ReCheckConnectivity()
        {
            if (_internetStatus != InternetConnectivityStatus.Identifying)
            {
                _internetStatus   = InternetConnectivityStatus.Identifying;
                _upnpDeviceStatus = UPnPDeviceStatus.Identifying;

                _connectivityCheckTimer.Change(1000, Timeout.Infinite);
            }
        }
        private void ConnectivityCheckTimerCallback(object state)
        {
            if (_upnpDeviceStatus == UPnPDeviceStatus.Identifying)
            {
                _upnpDevice = null;
            }

            InternetConnectivityStatus newInternetStatus = InternetConnectivityStatus.Identifying;
            UPnPDeviceStatus           newUPnPStatus;

            if (_profile.EnableUPnP)
            {
                newUPnPStatus = UPnPDeviceStatus.Identifying;
            }
            else
            {
                newUPnPStatus = UPnPDeviceStatus.Disabled;
            }

            try
            {
                if (_profile.Proxy != null)
                {
                    switch (_profile.Proxy.Type)
                    {
                    case NetProxyType.Http:
                        newInternetStatus = InternetConnectivityStatus.HttpProxyInternetConnection;
                        break;

                    case NetProxyType.Socks5:
                        newInternetStatus = InternetConnectivityStatus.Socks5ProxyInternetConnection;
                        break;

                    default:
                        throw new NotSupportedException("Proxy type not supported.");
                    }

                    newUPnPStatus = UPnPDeviceStatus.Disabled;
                    return;
                }

                NetworkInfo defaultNetworkInfo = NetUtilities.GetDefaultNetworkInfo();
                if (defaultNetworkInfo == null)
                {
                    //no internet available;
                    newInternetStatus = InternetConnectivityStatus.NoInternetConnection;
                    newUPnPStatus     = UPnPDeviceStatus.Disabled;
                    return;
                }

                if (!NetUtilities.IsPrivateIP(defaultNetworkInfo.LocalIP))
                {
                    //public ip so, direct internet connection available
                    newInternetStatus = InternetConnectivityStatus.DirectInternetConnection;
                    newUPnPStatus     = UPnPDeviceStatus.Disabled;
                    _localLiveIP      = defaultNetworkInfo.LocalIP;
                    return;
                }
                else
                {
                    _localLiveIP = null;
                }

                if (newUPnPStatus == UPnPDeviceStatus.Disabled)
                {
                    newInternetStatus = InternetConnectivityStatus.NatOrFirewalledInternetConnection;
                    return;
                }

                //check for upnp device

                if (defaultNetworkInfo.LocalIP.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    newInternetStatus = InternetConnectivityStatus.NatOrFirewalledInternetConnection;
                    newUPnPStatus     = UPnPDeviceStatus.Disabled;
                    return;
                }

                try
                {
                    if ((_upnpDevice == null) || (!_upnpDevice.NetworkBroadcastAddress.Equals(defaultNetworkInfo.BroadcastIP)))
                    {
                        _upnpDevice = InternetGatewayDevice.Discover(defaultNetworkInfo.BroadcastIP, 2000);
                    }

                    newInternetStatus = InternetConnectivityStatus.NatInternetConnectionViaUPnPRouter;
                }
                catch
                {
                    newInternetStatus = InternetConnectivityStatus.NatOrFirewalledInternetConnection;
                    newUPnPStatus     = UPnPDeviceStatus.DeviceNotFound;
                    throw;
                }

                //find external ip from router
                try
                {
                    _upnpExternalIP = _upnpDevice.GetExternalIPAddress();

                    if (_upnpExternalIP.ToString() == "0.0.0.0")
                    {
                        newInternetStatus = InternetConnectivityStatus.NoInternetConnection;
                        newUPnPStatus     = UPnPDeviceStatus.Disabled;
                        return; //external ip not available so no internet connection available
                    }
                    else if (NetUtilities.IsPrivateIP(_upnpExternalIP))
                    {
                        newUPnPStatus = UPnPDeviceStatus.ExternalIpPrivate;
                        return; //no use of doing port forwarding for private upnp ip address
                    }
                }
                catch
                {
                    _upnpExternalIP = null;
                }

                //do upnp port forwarding for Bit Chat
                if (_upnpDevice.ForwardPort(ProtocolType.Tcp, _localPort, new IPEndPoint(defaultNetworkInfo.LocalIP, _localPort), "Bit Chat", true))
                {
                    newUPnPStatus = UPnPDeviceStatus.PortForwarded;
                }
                else
                {
                    newUPnPStatus = UPnPDeviceStatus.PortForwardingFailed;
                }

                //do upnp port forwarding for DHT
                _upnpDevice.ForwardPort(ProtocolType.Udp, _dhtClient.LocalPort, new IPEndPoint(defaultNetworkInfo.LocalIP, _dhtClient.LocalPort), "Bit Chat DHT", true);
            }
            catch (Exception ex)
            {
                Debug.Write("ConnectionManager.ConnectivityCheckTimerCallback", ex);
            }
            finally
            {
                try
                {
                    //validate change in status by performing tests
                    if (_internetStatus != newInternetStatus)
                    {
                        switch (newInternetStatus)
                        {
                        case InternetConnectivityStatus.NoInternetConnection:
                            _localLiveIP    = null;
                            _upnpExternalIP = null;
                            _connectivityCheckExternalEP = null;
                            break;

                        case InternetConnectivityStatus.HttpProxyInternetConnection:
                        case InternetConnectivityStatus.Socks5ProxyInternetConnection:
                            if (!_profile.Proxy.IsProxyAvailable())
                            {
                                newInternetStatus = InternetConnectivityStatus.NoInternetConnection;
                            }

                            _localLiveIP    = null;
                            _upnpExternalIP = null;
                            _connectivityCheckExternalEP = null;
                            break;

                        default:
                            if (WebUtilities.IsWebAccessible())
                            {
                                switch (newInternetStatus)
                                {
                                case InternetConnectivityStatus.DirectInternetConnection:
                                    if (!DoWebCheckIncomingConnection(_localPort))
                                    {
                                        _localLiveIP = null;
                                    }

                                    break;

                                case InternetConnectivityStatus.NatOrFirewalledInternetConnection:
                                    if (!DoWebCheckIncomingConnection(_localPort))
                                    {
                                        _connectivityCheckExternalEP = null;
                                    }

                                    break;

                                case InternetConnectivityStatus.NatInternetConnectionViaUPnPRouter:
                                    break;

                                default:
                                    _localLiveIP    = null;
                                    _upnpExternalIP = null;
                                    _connectivityCheckExternalEP = null;
                                    break;
                                }
                            }
                            else
                            {
                                newInternetStatus            = InternetConnectivityStatus.NoInternetConnection;
                                _localLiveIP                 = null;
                                _upnpExternalIP              = null;
                                _connectivityCheckExternalEP = null;
                            }
                            break;
                        }
                    }

                    if ((newInternetStatus == InternetConnectivityStatus.NatInternetConnectionViaUPnPRouter) && (_upnpDeviceStatus != newUPnPStatus) && (newUPnPStatus == UPnPDeviceStatus.PortForwarded))
                    {
                        if (_upnpDeviceStatus == UPnPDeviceStatus.PortForwardedNotAccessible)
                        {
                            newUPnPStatus = UPnPDeviceStatus.PortForwardedNotAccessible;
                        }
                        else if (!DoWebCheckIncomingConnection(_localPort))
                        {
                            newUPnPStatus = UPnPDeviceStatus.PortForwardedNotAccessible;
                        }
                    }

                    if ((_internetStatus != newInternetStatus) || (_upnpDeviceStatus != newUPnPStatus))
                    {
                        _internetStatus   = newInternetStatus;
                        _upnpDeviceStatus = newUPnPStatus;

                        if (this.ExternalEndPoint == null)
                        {
                            //if no incoming connection possible

                            if (_dhtClient.GetTotalNodes() < DhtClient.KADEMLIA_K)
                            {
                                _dhtSeedingTracker.LookupOnly = true;
                                _dhtSeedingTracker.ScheduleUpdateNow(); //start finding dht nodes immediately
                            }
                            else
                            {
                                _dhtSeedingTracker.StopTracking(); //we have enough dht nodes and can stop seeding tracker
                            }
                        }
                        else
                        {
                            _dhtSeedingTracker.LookupOnly = false;

                            if (!_dhtSeedingTracker.IsTrackerRunning)
                            {
                                _dhtSeedingTracker.StartTracking(); //keep seeding tracker running for other peers to find dht bootstrap nodes
                            }
                        }

                        InternetConnectivityStatusChanged?.Invoke(this, EventArgs.Empty);
                    }

                    //schedule next check
                    if (_connectivityCheckTimer != null)
                    {
                        if ((_internetStatus == InternetConnectivityStatus.NoInternetConnection) || (_upnpDeviceStatus == UPnPDeviceStatus.DeviceNotFound) || (_upnpDeviceStatus == UPnPDeviceStatus.PortForwardingFailed))
                        {
                            _connectivityCheckTimer.Change(10000, Timeout.Infinite);
                        }
                        else
                        {
                            _connectivityCheckTimer.Change(CONNECTIVITY_CHECK_TIMER_INTERVAL, Timeout.Infinite);
                        }
                    }
                }
                catch
                { }
            }
        }