public RelayTunnel( ILogger logger, TunnelMetrics metrics, ServiceNamespaceOptions serviceNamespace, string entityPath, int remoteConfigurationKey, int ttlSeconds) { if (string.IsNullOrWhiteSpace(entityPath)) { throw new ArgumentNullException(nameof(entityPath)); } _log = logger.ForContext(GetType()); _uplinkPumps = new ConcurrentDictionary <object, UplinkPump>(); _establishLock = new SemaphoreSlim(1, 1); _relay = new UriBuilder("sb", serviceNamespace.ServiceNamespace, -1, entityPath).Uri; _tokenProvider = serviceNamespace.CreateSasTokenProvider(); _ttl = TimeSpan.FromSeconds(ttlSeconds); _tunnelPreamble = new TunnelPreamble(remoteConfigurationKey); _canAcceptUntil = DateTime.MaxValue; _metrics = metrics; }
private async Task StreamAccepted(Task <HybridConnectionStream> prev) { try { #pragma warning disable 4014 _relayListener.AcceptConnectionAsync().ContinueWith(StreamAccepted); #pragma warning restore 4014 if (prev.Exception != null) { throw prev.Exception; } var relayStream = prev.Result; if (relayStream != null) { var preamble = await TunnelPreamble.ReadAsync(relayStream); var factory = _metadata.GetLocalDataChannelFactory(preamble.ConfigurationKey); if (factory == null) { CloseRelayStream(relayStream, $"Incoming connection for {preamble.ConfigurationKey} is not permitted"); return; } _log.Debug("Relay: {idx}:{relay}. Incoming connection for {configurationKey}", _forwarderIdx, _relayListener.Address, preamble.ConfigurationKey); EstablishTunnel(relayStream, factory); } } catch (Exception e) { _log.Error(e, "Relay: {idx}:{relay}. Error accepting connection", _forwarderIdx, _relayListener.Address); } }