diff --git a/CHANGELOG.md b/CHANGELOG.md index 8157f92..2cca05d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## v0.6.3 - Allow users to use tokio v2.4.0 in their projects. See [#106](https://github.com/gbaranski/ezsockets/pull/106). +- Force-close clients if they encounter an IO error, since an IO error might mean the client is hanging (e.g. after an IP address change) and should be reconstructed. - Return `CloseCode::Abnormal` from keepalive timeouts instead of `CloseCode::Normal`. - Fix DDOS by honest clients when servers check capacity *after* clients connect. diff --git a/src/client.rs b/src/client.rs index 86c59dd..dccb39a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -526,20 +526,24 @@ impl ClientActor { ); } match result { - Err(WSError::ConnectionClosed) - | Err(WSError::AlreadyClosed) - | Err(WSError::Io(_)) - | Err(WSError::Tls(_)) => { + Err(WSError::ConnectionClosed) | Err(WSError::AlreadyClosed) => { // either: // A) The connection was closed via the close protocol, so we will allow the stream to // handle it. // B) We already tried and failed to submit another message, so now we are // waiting for other parts of the select! to shut us down. - // C) An IO error means the connection closed unexpectedly, so we can try to reconnect when - // the stream fails. + } + Err(WSError::Io(_)) | Err(WSError::Tls(_)) => { + // An IO error means the connection closed unexpectedly. We don't know if the stream is + // hanging or if it will shut down, so we force-close the socket. + // + // There are edge cases where this erroneously closes the connection even though we'd rather + // use auto-reconnect. TODO: isolate the error cases where force-closing is appropriate. + return Err(Error::from("encountered IO sink close error, force-closing client actor since connection \ + might be hanging")); } Err(_) if !closed_self => { - return Err(Error::from("unexpected sink error, aborting client actor")) + return Err(Error::from("unexpected sink error, aborting client actor")); } _ => (), }