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(); }
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); }
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; } }