Esempio n. 1
0
        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);
            }
        }