Beispiel #1
0
        async Task StartClientConnectionAsync(Task <Socket> socketTask)
        {
            // If this throws, it will have cleaned up before getting here, so we don't need to
            // handle cleanup.
            EpoxyNetworkStream epoxyStream = await EpoxyNetworkStream.MakeAsync(
                socketFunc : () => socketTask,
                streamFunc : socket => EpoxyNetworkStream.MakeServerStreamAsync(socket, tlsConfig, logger),
                timeoutConfig : timeoutConfig,
                logger : logger);

            // We now have a completely established EpoxyNetworkStream that will eventually need to
            // be shutdown. None of the code between here and adding the connection to our collection
            // will throw (for network I/O reasons), so we'll safely save the connection. (The
            // intervening code may throw for things like OOM. If it does, we've got bigger problems
            // that we likely won't be able to recover from anyway. Ignoring that contingency for
            // now.)
            var connection = EpoxyConnection.MakeServerConnection(
                parentTransport,
                this,
                serviceHost,
                epoxyStream,
                logger,
                metrics);

            lock (connectionsLock)
            {
                connections.Add(connection);
            }

            logger.Site().Debug("Setup server-side connection for {0}. Starting Epoxy handshake.", connection.RemoteEndPoint);
            await connection.StartAsync();
        }
Beispiel #2
0
        internal void InformDisconnected(EpoxyConnection connection, Error error)
        {
            connections.Remove(connection);
            var args = new DisconnectedEventArgs(connection, error);

            OnDisconnected(args);
        }
Beispiel #3
0
        private async Task AcceptAsync(CancellationToken t)
        {
            logger.Site().Information("Accepting connections on {0}", ListenEndpoint);
            while (!t.IsCancellationRequested)
            {
                Socket             socket      = null;
                EpoxyNetworkStream epoxyStream = null;

                try
                {
                    socket = await listener.AcceptSocketAsync();

                    logger.Site().Debug("Accepted connection from {0}.", socket.RemoteEndPoint);

                    EpoxyTransport.ConfigureSocketKeepAlive(socket, timeoutConfig, logger);

                    epoxyStream = await EpoxyNetworkStream.MakeServerStreamAsync(socket, tlsConfig, logger);

                    socket = null; // epoxyStream now owns the socket

                    var connection = EpoxyConnection.MakeServerConnection(
                        parentTransport,
                        this,
                        serviceHost,
                        epoxyStream,
                        logger,
                        metrics);

                    // connection now owns the EpoxyNetworkStream
                    epoxyStream = null;

                    lock (connectionsLock)
                    {
                        connections.Add(connection);
                    }

                    await connection.StartAsync();

                    logger.Site().Debug("Started server-side connection for {0}", connection.RemoteEndPoint);
                }
                catch (AuthenticationException ex)
                {
                    logger.Site().Error(ex, "Failed to authenticate remote connection from {0}", socket?.RemoteEndPoint);
                    ShutdownSocketSafe(socket, epoxyStream);
                }
                catch (SocketException ex)
                {
                    logger.Site().Error(ex, "Accept failed with error {0}.", ex.SocketErrorCode);
                    ShutdownSocketSafe(socket, epoxyStream);
                }
                catch (ObjectDisposedException)
                {
                    ShutdownSocketSafe(socket, epoxyStream);
                }
            }

            logger.Site().Information("Shutting down connection on {0}", ListenEndpoint);
        }
Beispiel #4
0
        public async Task <EpoxyConnection> ConnectToAsync(IPEndPoint endpoint, CancellationToken ct)
        {
            logger.Site().Information("Connecting to {0}.", endpoint);

            Socket socket = MakeClientSocket();
            await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, endpoint, state : null);

            // TODO: keep these in some master collection for shutdown
            var connection = EpoxyConnection.MakeClientConnection(this, socket, logger, metrics);
            await connection.StartAsync();

            return(connection);
        }
Beispiel #5
0
        public async Task <EpoxyConnection> ConnectToAsync(IPEndPoint endpoint, CancellationToken ct)
        {
            Log.Information("{0}.{1}: Connecting to {2}.", nameof(EpoxyTransport), nameof(ConnectToAsync), endpoint);

            Socket socket = MakeClientSocket();
            await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, endpoint, state : null);

            // TODO: keep these in some master collection for shutdown
            var connection = EpoxyConnection.MakeClientConnection(this, socket);
            await connection.StartAsync();

            return(connection);
        }
Beispiel #6
0
        private async Task AcceptAsync(CancellationToken t)
        {
            Log.Information("{0}.{1}: Accepting connections...", this, nameof(AcceptAsync));
            while (!t.IsCancellationRequested)
            {
                Socket socket = null;

                try
                {
                    socket = await listener.AcceptSocketAsync();

                    var connection = EpoxyConnection.MakeServerConnection(
                        parentTransport,
                        this,
                        serviceHost,
                        socket);
                    socket = null; // connection now owns the socket and will close it

                    lock (connectionsLock)
                    {
                        connections.Add(connection);
                    }

                    await connection.StartAsync();

                    Log.Debug("{0}.{1}: Accepted connection from {2}.",
                              this, nameof(AcceptAsync), connection.RemoteEndPoint);
                }
                catch (SocketException ex)
                {
                    Log.Fatal(ex, "{0}.{1}: Accept failed with error {2}.",
                              this, nameof(AcceptAsync), ex.SocketErrorCode);

                    ShutdownSocketSafe(socket);
                }
                catch (ObjectDisposedException)
                {
                    ShutdownSocketSafe(socket);

                    // TODO: ignoring this exception is needed during shutdown,
                    //       but there should be a cleaner way. We should
                    //       switch to having a proper life-cycle for a
                    //       connection.
                }
            }
            Log.Information("{0}.{1}: Shutting down.", this, nameof(AcceptAsync));
        }
Beispiel #7
0
        private async Task AcceptAsync(CancellationToken t)
        {
            logger.Site().Information("Accepting connections on {0}", ListenEndpoint);
            while (!t.IsCancellationRequested)
            {
                Socket socket = null;

                try
                {
                    socket = await listener.AcceptSocketAsync();

                    var connection = EpoxyConnection.MakeServerConnection(
                        parentTransport,
                        this,
                        serviceHost,
                        socket,
                        logger,
                        metrics);
                    socket = null; // connection now owns the socket and will close it

                    lock (connectionsLock)
                    {
                        connections.Add(connection);
                    }

                    await connection.StartAsync();

                    logger.Site().Debug("Accepted connection from {0}.", connection.RemoteEndPoint);
                }
                catch (SocketException ex)
                {
                    logger.Site().Error(ex, "Accept failed with error {0}.", ex.SocketErrorCode);

                    ShutdownSocketSafe(socket, logger);
                }
                catch (ObjectDisposedException)
                {
                    ShutdownSocketSafe(socket, logger);

                    // TODO: ignoring this exception is needed during shutdown,
                    //       but there should be a cleaner way. We should
                    //       switch to having a proper life-cycle for a
                    //       connection.
                }
            }
            logger.Site().Information("Shutting down connection on {0}", ListenEndpoint);
        }
Beispiel #8
0
        async Task StartClientConnectionAsync(Socket socket)
        {
            EpoxyNetworkStream epoxyStream = null;

            try
            {
                EpoxyTransport.ConfigureSocketKeepAlive(socket, timeoutConfig, logger);

                epoxyStream = await EpoxyNetworkStream.MakeServerStreamAsync(socket, tlsConfig, logger);

                socket = null; // epoxyStream now owns the socket

                var connection = EpoxyConnection.MakeServerConnection(
                    parentTransport,
                    this,
                    serviceHost,
                    epoxyStream,
                    logger,
                    metrics);

                // connection now owns the EpoxyNetworkStream
                epoxyStream = null;

                lock (connectionsLock)
                {
                    connections.Add(connection);
                }

                logger.Site().Debug("Setup server-side connection for {0}. Starting Epoxy handshake.", connection.RemoteEndPoint);
                await connection.StartAsync();
            }
            catch (Exception)
            {
                ShutdownSocketSafe(socket, epoxyStream);
                throw;
            }
        }
Beispiel #9
0
        internal Error InformConnected(EpoxyConnection connection)
        {
            var args = new ConnectedEventArgs(connection);

            return(OnConnected(args));
        }