public void Initialize() { Logger.Info("Initializing networking"); while (true) { try { _stunQuery = null; CheckNatType(); if (_stunQuery != null) { break; } } catch (Exception e) { Logger.Error("Unable to initialize networking! Retrying", e); Thread.Sleep(5000); } } if (_stunQuery.NetworkType == StunNetworkType.UdpBlocked) { Logger.Warn("First NAT detectiont return that UDP is fully blocked. Trying second time with timeout of 5 seconds ..."); Thread.Sleep(5000); Initialize(); return; } _remoteEp = _stunQuery.PublicEndPoint; var internalPort = ((IPEndPoint)_socket.LocalEndPoint).Port; Logger.Debug($"P2P connections are listen as external {_stunQuery.PublicEndPoint.Address}:{_stunQuery.PublicEndPoint.Port}, local bind is {_bindEp.Address}:{internalPort}"); Logger.Info($"Bound local socket at {(IPEndPoint) _socket.LocalEndPoint}"); _portMapping = new Mapping(Protocol.Udp, internalPort, _stunQuery.PublicEndPoint.Port, $"RHMS Internal Peer {_connectionManager.GetSelfHostId()} Map"); Monitor.Enter(_natUpnpCreateLocker); Task.Run(async() => { try { var discoverer = new NatDiscoverer(); var cts = new CancellationTokenSource(10000); var device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts); await device.CreatePortMapAsync(_portMapping); Logger.Info($"Created UPnP mapping {_portMapping}"); } catch (Exception e) { Logger.Error("Unable to create UPnP mapping!", e); } }).Wait(); Monitor.Exit(_natUpnpCreateLocker); NetworkStartAcceptingData(); }
private bool PerformNatQueryOn(string host, int port) { Logger.Debug($"Performing STUN query to {host}:{port}"); _stunQuery = StunQuery.Perform(_socket, host, port); if (_stunQuery == null || _stunQuery.NetworkType == StunNetworkType.CommunicationError) { _stunQuery = null; Logger.Debug($"STUN query to {host}:{port} failed with communication error"); return(false); } return(true); }