Exemple #1
0
        private async Task AcceptNewClientAsync(
            TcpClient client,
            ConnectionSetting connectionSettings,
            CancellationToken cancellationToken)
        {
            ILifetimeScope newScope = _scope.BeginLifetimeScope(
                ConnectionScopeTag,
                builder =>
            {
                builder.RegisterInstance(
                    new ConnectionInformation(
                        client.Client.LocalEndPoint.ToString(),
                        client.Client.RemoteEndPoint.ToString()));

                builder.RegisterInstance(new SecurableConnection(client.GetStream(), _keyProvider.GetKey(connectionSettings.Certificate)))
                .As <SecurableConnection>()
                .As <IConnectionSecurity>()
                .As <IVariableStreamReader>();

                builder.RegisterInstance(connectionSettings);

                builder.Register(c => c.ResolveKeyed <IAuthenticationTransport>(connectionSettings.Protocol))
                .As <IAuthenticationTransport>();
            }
                );

            var newSession = newScope.ResolveKeyed <IProtocolSession>(connectionSettings.Protocol);

            using (await SemaphoreLock.GetLockAsync(_sessionSemaphore, cancellationToken))
            {
                _sessions.Add(new SessionHolder(newSession, newSession.RunAsync(cancellationToken), newScope));
            }
        }
Exemple #2
0
        public async Task RunAsync(CancellationToken cancellationToken)
        {
            _log.Information($"Opening ports: {string.Join(",", _settings.Connections.Select(p => p.Port.ToString()))}");

            TcpListener[] listeners = _settings.Connections
                                      .Select(p => new TcpListener(IPAddress.Any, p.Port))
                                      .ToArray();

            foreach (TcpListener l in listeners)
            {
                l.Start();
            }

            Task <TcpClient>[] listenerTasks = listeners
                                               .Select(tcp => tcp.AcceptTcpClientAsync())
                                               .ToArray();

            while (!cancellationToken.IsCancellationRequested)
            {
                var tasks = new Task[listenerTasks.Length + _sessions.Count];
                Array.Copy(listenerTasks, 0, tasks, 0, listenerTasks.Length);
                _sessions.Select(s => s.Task).ToList().CopyTo(tasks, listenerTasks.Length);

                int  completedIndex = Task.WaitAny(tasks);
                Task task           = tasks[completedIndex];

                if (task is Task <TcpClient> tcpTask)
                {
                    // This is a new connection task
                    TcpClient         client             = tcpTask.Result;
                    ConnectionSetting connectionSettings = _settings.Connections[completedIndex];
                    await AcceptNewClientAsync(client, connectionSettings, cancellationToken);

                    // Wait for another connection
                    listenerTasks[completedIndex] = listeners[completedIndex].AcceptTcpClientAsync();
                }
                else
                {
                    // One of the existing connections is closing
                    using (await SemaphoreLock.GetLockAsync(_sessionSemaphore, cancellationToken))
                    {
                        int           sessionIndex   = completedIndex - listenerTasks.Length;
                        SessionHolder closingSession = _sessions[sessionIndex];
                        _log.Information($"Closing session {closingSession.Session.Id}...");
                        _sessions.RemoveAt(sessionIndex);
                        closingSession.Scope.Dispose();
                    }
                }
            }

            foreach (TcpListener l in listeners)
            {
                l.Stop();
            }
        }
Exemple #3
0
 public async Task Close(CancellationToken cancellationToken)
 {
     using (await SemaphoreLock.GetLockAsync(_sessionSemaphore, cancellationToken))
     {
         Task[] closing = _sessions.Select(session => session.CloseAsync(cancellationToken)).ToArray();
         Task.WaitAll(closing, cancellationToken);
         Task.WaitAll(_sessionLifetimes.ToArray(), cancellationToken);
         _sessions         = null;
         _sessionLifetimes = null;
     }
 }
Exemple #4
0
        public async Task Close(CancellationToken cancellationToken)
        {
            using (await SemaphoreLock.GetLockAsync(_sessionSemaphore, cancellationToken))
            {
                foreach (SessionHolder session in _sessions)
                {
                    session.Scope.Dispose();
                }

                await Task.WhenAll(_sessions.Select(s => s.Task));

                _sessions = null;
            }
        }
Exemple #5
0
        public async Task Start(CancellationToken cancellationToken)
        {
            TcpListener[] listeners = _ports
                                      .Select(p => new TcpListener(IPAddress.Any, p))
                                      .ToArray();

            foreach (var l in listeners)
            {
                l.Start();
            }

            Task <TcpClient>[] tasks =
                listeners.Select(tcp => tcp.AcceptTcpClientAsync())
                .ToArray();

            while (!cancellationToken.IsCancellationRequested)
            {
                int taskCompleted = Task.WaitAny(tasks);

                TcpClient client = tasks[taskCompleted].Result;

                using (await SemaphoreLock.GetLockAsync(_sessionSemaphore, cancellationToken))
                {
                    var securableConnection = new SecurableConnection(client.GetStream());
                    securableConnection.Certificate = ServerCertificate;
                    var session = InitiateSession(
                        securableConnection,
                        client.Client.LocalEndPoint,
                        client.Client.RemoteEndPoint);
                    _sessions.Add(session);
                    _sessionLifetimes.Add(session.Start(cancellationToken));
                }

                // Wait for another connection
                tasks[taskCompleted] = listeners[taskCompleted].AcceptTcpClientAsync();
            }

            foreach (var l in listeners)
            {
                l.Stop();
            }
        }
Exemple #6
0
        public async Task SendMessageAsync(ImapMessage message, Encoding encoding, CancellationToken cancellationToken)
        {
            using (await SemaphoreLock.GetLockAsync(_sendSemaphore, cancellationToken))
            {
                var builder = new StringBuilder();
                builder.Append(message.Tag);
                foreach (IMessageData data in message.Data)
                {
                    if (data is LiteralMessageData literal)
                    {
                        builder.Append("}");
                        builder.Append(literal.Length);
                        builder.AppendLine("}");
                        await _connection.WriteAsync(builder.ToString(), encoding, cancellationToken);

                        builder.Clear();
                    }
                    else
                    {
                        if (builder.Length > 0)
                        {
                            builder.Append(" ");
                        }

                        builder.Append(data.ToMessageString());
                    }
                }

                if (builder.Length > 0)
                {
                    _logger.Verbose("IMAP -> " + builder);
                    builder.AppendLine();
                    await _connection.WriteAsync(builder.ToString(), encoding, cancellationToken);
                }
            }
        }