Fix nonblocking behavior
A new nonblocking socket may not have finished connecting yet, so reads and writes can return ENOTCONNECTED which we should reinterpret into a WantRead or WantWrite Closes #323
This commit is contained in:
parent
ccab187f5a
commit
053c924d5a
|
|
@ -95,7 +95,7 @@ unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_
|
||||||
match state.stream.write(buf) {
|
match state.stream.write(buf) {
|
||||||
Ok(len) => len as c_int,
|
Ok(len) => len as c_int,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if err.kind() == io::ErrorKind::WouldBlock {
|
if retriable_error(&err) {
|
||||||
BIO_set_retry_write(bio);
|
BIO_set_retry_write(bio);
|
||||||
}
|
}
|
||||||
state.error = Some(err);
|
state.error = Some(err);
|
||||||
|
|
@ -112,7 +112,7 @@ unsafe extern "C" fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int)
|
||||||
match state.stream.read(buf) {
|
match state.stream.read(buf) {
|
||||||
Ok(len) => len as c_int,
|
Ok(len) => len as c_int,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if err.kind() == io::ErrorKind::WouldBlock {
|
if retriable_error(&err) {
|
||||||
BIO_set_retry_read(bio);
|
BIO_set_retry_read(bio);
|
||||||
}
|
}
|
||||||
state.error = Some(err);
|
state.error = Some(err);
|
||||||
|
|
@ -121,6 +121,13 @@ unsafe extern "C" fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn retriable_error(err: &io::Error) -> bool {
|
||||||
|
match err.kind() {
|
||||||
|
io::ErrorKind::WouldBlock | io::ErrorKind::NotConnected => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn bputs<S: Write>(bio: *mut BIO, s: *const c_char) -> c_int {
|
unsafe extern "C" fn bputs<S: Write>(bio: *mut BIO, s: *const c_char) -> c_int {
|
||||||
bwrite::<S>(bio, s, strlen(s) as c_int)
|
bwrite::<S>(bio, s, strlen(s) as c_int)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1070,16 +1070,10 @@ impl<S: Read + Write> SslStream<S> {
|
||||||
if ret > 0 {
|
if ret > 0 {
|
||||||
Ok(stream)
|
Ok(stream)
|
||||||
} else {
|
} else {
|
||||||
match stream.make_old_error(ret) {
|
match stream.make_error(ret) {
|
||||||
SslError::StreamError(e) => {
|
|
||||||
// This is fine - nonblocking sockets will finish the handshake in read/write
|
// This is fine - nonblocking sockets will finish the handshake in read/write
|
||||||
if e.kind() == io::ErrorKind::WouldBlock {
|
Error::WantRead(..) | Error::WantWrite(..) => Ok(stream),
|
||||||
Ok(stream)
|
_ => Err(stream.make_old_error(ret)),
|
||||||
} else {
|
|
||||||
Err(SslError::StreamError(e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e => Err(e),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1092,16 +1086,10 @@ impl<S: Read + Write> SslStream<S> {
|
||||||
if ret > 0 {
|
if ret > 0 {
|
||||||
Ok(stream)
|
Ok(stream)
|
||||||
} else {
|
} else {
|
||||||
match stream.make_old_error(ret) {
|
match stream.make_error(ret) {
|
||||||
SslError::StreamError(e) => {
|
|
||||||
// This is fine - nonblocking sockets will finish the handshake in read/write
|
// This is fine - nonblocking sockets will finish the handshake in read/write
|
||||||
if e.kind() == io::ErrorKind::WouldBlock {
|
Error::WantRead(..) | Error::WantWrite(..) => Ok(stream),
|
||||||
Ok(stream)
|
_ => Err(stream.make_old_error(ret)),
|
||||||
} else {
|
|
||||||
Err(SslError::StreamError(e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e => Err(e),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue