tdfischer / pto

IRC to Matrix bridge
Apache License 2.0
48 stars 8 forks source link

Incorrect usage of non blocking io with openssl #60

Open erikjohnston opened 8 years ago

erikjohnston commented 8 years ago

Currently PTO uses the Read + Write traits of SslStream with MIO, however OpenSSL may return error conditions that require special handling when used with non-blocking sockets. These are not exposed via the Read + Write traits (due to them returning io::Result), which eventually causes PTO to panic.

To use OpenSSL with non-blocking sockets correctly, PTO should use SslStream::{ssl_read, ssl_write} and handle the ssl::Error::{WantRead, WantWrite} conditions correctly.

An alternative may be to use the Telos library instead of rust-openssl.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/31917956-incorrect-usage-of-non-blocking-io-with-openssl?utm_campaign=plugin&utm_content=tracker%2F27545356&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F27545356&utm_medium=issues&utm_source=github).
ara4n commented 8 years ago

The actual symptoms here are

WARN:pto::bridge: Could not handle matrix event: Error { repr: Os { code: 11, message: "Resource temporarily unavailable" } }
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Custom(Custom { kind: Other, error: Ssl([OpenSslError { library: "SSL routines", function: "SSL3_WRITE_PENDING", reason: "bad write retry" }]) }) }', ../src/libcore/result.rs:688

...in the middle of streaming lots of initial sync data through to the IRC client over SSL. I probably never noticed this before because I was either talking SSL over localhost from my irc client to my PTO, or just not speaking SSL at all given localhost stuff is no longer SSL'd.