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 { } } }