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(); }
internal void InformDisconnected(EpoxyConnection connection, Error error) { connections.Remove(connection); var args = new DisconnectedEventArgs(connection, error); OnDisconnected(args); }
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); }
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); }
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); }
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)); }
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); }
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; } }
internal Error InformConnected(EpoxyConnection connection) { var args = new ConnectedEventArgs(connection); return(OnConnected(args)); }