Beispiel #1
0
 void Add(SmtpSession session)
 {
     lock (_sessionsLock)
     {
         _sessions.Add(session);
     }
 }
Beispiel #2
0
 void Remove(SmtpSession session)
 {
     lock (_sessionsLock)
     {
         _sessions.Remove(session);
     }
 }
Beispiel #3
0
        /// <summary>
        /// Listen for SMTP traffic on the given endpoint.
        /// </summary>
        /// <param name="endpointDefinition">The definition of the endpoint to listen on.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A task which performs the operation.</returns>
        private async Task ListenAsync(IEndpointDefinition endpointDefinition, CancellationToken cancellationToken)
        {
            var      tcpListener   = new TcpListener(endpointDefinition.Endpoint);
            EndPoint localEndPoint = tcpListener.LocalEndpoint;

            tcpListener.Start();

            // keep track of the running tasks for disposal
            var sessions = new ConcurrentDictionary <SmtpSession, SmtpSession>();

            try
            {
                OnEndPointStarted(new EndPointEventArgs(endpointDefinition, localEndPoint));

                while (cancellationToken.IsCancellationRequested == false)
                {
                    // wait for a client connection
                    var tcpClient = await tcpListener.AcceptTcpClientAsync().WithCancellation(cancellationToken).ConfigureAwait(false);

                    var networkClient = new NetworkClient(tcpClient.GetStream(), _options.NetworkBufferSize, _options.NetworkBufferReadTimeout);

                    if (endpointDefinition.IsSecure && _options.ServerCertificate != null)
                    {
                        await networkClient.UpgradeAsync(_options.ServerCertificate, _options.SupportedSslProtocols, cancellationToken);

                        cancellationToken.ThrowIfCancellationRequested();
                    }

                    // create a new session to handle the connection
                    var session = new SmtpSession(_options, tcpClient, networkClient);
                    sessions.TryAdd(session, session);

                    OnSessionCreated(new SessionEventArgs(session.Context));

                    session.Run(cancellationToken);

#pragma warning disable 4014
                    session.Task
                    .ContinueWith(t =>
                    {
                        if (sessions.TryRemove(session, out SmtpSession s))
                        {
                            s.Dispose();
                        }

                        OnSessionCompleted(new SessionEventArgs(session.Context));
                    },
                                  cancellationToken);
#pragma warning restore 4014
                }

                // the server has been cancelled, wait for the tasks to complete
                await Task.WhenAll(sessions.Keys.Select(s => s.Task)).ConfigureAwait(false);
            }
            finally
            {
                tcpListener.Stop();
                OnEndPointStopped(new EndPointEventArgs(endpointDefinition, localEndPoint));
            }
        }
Beispiel #4
0
        /// <summary>
        /// Listen for SMTP traffic on the given endpoint.
        /// </summary>
        /// <param name="endpointDefinition">The definition of the endpoint to listen on.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A task which performs the operation.</returns>
        async Task ListenAsync(IEndpointDefinition endpointDefinition, CancellationToken cancellationToken)
        {
            // keep track of the running tasks for disposal
            var sessions = new ConcurrentDictionary <SmtpSession, SmtpSession>();

            using (var endpointListener = _options.EndpointListenerFactory.CreateListener(endpointDefinition))
            {
                while (cancellationToken.IsCancellationRequested == false)
                {
                    var sessionContext = new SmtpSessionContext(_options, endpointDefinition);

                    // wait for a client connection
                    var stream = await endpointListener.GetStreamAsync(sessionContext, cancellationToken).ConfigureAwait(false);

                    cancellationToken.ThrowIfCancellationRequested();

                    sessionContext.NetworkClient = new NetworkClient(stream, _options.NetworkBufferSize, _options.NetworkBufferReadTimeout);

                    if (endpointDefinition.IsSecure && _options.ServerCertificate != null)
                    {
                        await sessionContext.NetworkClient.UpgradeAsync(_options.ServerCertificate, _options.SupportedSslProtocols, cancellationToken);

                        cancellationToken.ThrowIfCancellationRequested();
                    }

                    // create a new session to handle the connection
                    var session = new SmtpSession(sessionContext);
                    sessions.TryAdd(session, session);

                    OnSessionCreated(new SessionEventArgs(sessionContext));

                    session.Run(cancellationToken);

                    #pragma warning disable 4014
                    session.Task
                    .ContinueWith(t =>
                    {
                        if (sessions.TryRemove(session, out var s))
                        {
                            sessionContext.NetworkClient.Dispose();
                        }

                        OnSessionCompleted(new SessionEventArgs(sessionContext));
                    },
                                  cancellationToken);
                    #pragma warning restore 4014
                }

                // the server has been cancelled, wait for the tasks to complete
                await Task.WhenAll(sessions.Keys.Select(s => s.Task)).ConfigureAwait(false);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Listen for SMTP traffic on the given endpoint.
        /// </summary>
        /// <param name="endpoint">The endpoint to listen on.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A task which performs the operation.</returns>
        async Task ListenAsync(IPEndPoint endpoint, CancellationToken cancellationToken)
        {
            var tcpListener = new TcpListener(endpoint);

            tcpListener.Start();

            // keep track of the running tasks for disposal
            var sessions = new ConcurrentDictionary <SmtpSession, SmtpSession>();

            try
            {
                while (cancellationToken.IsCancellationRequested == false)
                {
                    // wait for a client connection
                    var tcpClient = await tcpListener.AcceptTcpClientAsync().WithCancellation(cancellationToken).ConfigureAwait(false);

                    // create a new session to handle the connection
                    var session = new SmtpSession(_options, tcpClient);
                    sessions.TryAdd(session, session);

                    OnSessionCreated(new SessionEventArgs(session.Context));

                    //Start Execute Session
                    session.Run(cancellationToken);

                    #pragma warning disable 4014
                    session.Task
                    .ContinueWith(t =>
                    {
                        if (sessions.TryRemove(session, out SmtpSession s))
                        {
                            s.Dispose();
                        }

                        OnSessionCompleted(new SessionEventArgs(session.Context));
                    },
                                  cancellationToken);
                    #pragma warning restore 4014
                }

                // the server has been cancelled, wait for the tasks to complete
                await Task.WhenAll(sessions.Keys.Select(s => s.Task)).ConfigureAwait(false);
            }
            finally
            {
                tcpListener.Stop();
            }
        }
Beispiel #6
0
            public void Run(SmtpSessionContext sessionContext, CancellationToken cancellationToken)
            {
                var session = new SmtpSession(sessionContext);

                Add(session);

                _smtpServer.OnSessionCreated(new SessionEventArgs(sessionContext));

                session.Run(
                    exception =>
                {
                    Remove(session);

                    sessionContext.NetworkClient.Dispose();

                    if (exception != null)
                    {
                        _smtpServer.OnSessionFaulted(new SessionFaultedEventArgs(sessionContext, exception));
                    }

                    _smtpServer.OnSessionCompleted(new SessionEventArgs(sessionContext));
                },
                    cancellationToken);
            }
 public SmtpSessionHandle(SmtpSession session, SmtpSessionContext sessionContext)
 {
     Session        = session;
     SessionContext = sessionContext;
 }