Commit 053c924d authored by Steven Fackler's avatar Steven Fackler
Browse files

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
parent ccab187f
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -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) {
        Ok(len) => len as c_int,
        Err(err) => {
            if err.kind() == io::ErrorKind::WouldBlock {
            if retriable_error(&err) {
                BIO_set_retry_write(bio);
            }
            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) {
        Ok(len) => len as c_int,
        Err(err) => {
            if err.kind() == io::ErrorKind::WouldBlock {
            if retriable_error(&err) {
                BIO_set_retry_read(bio);
            }
            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 {
    bwrite::<S>(bio, s, strlen(s) as c_int)
}
+8 −20
Original line number Diff line number Diff line
@@ -1070,16 +1070,10 @@ impl<S: Read + Write> SslStream<S> {
        if ret > 0 {
            Ok(stream)
        } else {
            match stream.make_old_error(ret) {
                SslError::StreamError(e) => {
            match stream.make_error(ret) {
                // This is fine - nonblocking sockets will finish the handshake in read/write
                    if e.kind() == io::ErrorKind::WouldBlock {
                        Ok(stream)
                    } else {
                        Err(SslError::StreamError(e))
                    }
                }
                e => Err(e),
                Error::WantRead(..) | Error::WantWrite(..) => Ok(stream),
                _ => Err(stream.make_old_error(ret)),
            }
        }
    }
@@ -1092,16 +1086,10 @@ impl<S: Read + Write> SslStream<S> {
        if ret > 0 {
            Ok(stream)
        } else {
            match stream.make_old_error(ret) {
                SslError::StreamError(e) => {
            match stream.make_error(ret) {
                // This is fine - nonblocking sockets will finish the handshake in read/write
                    if e.kind() == io::ErrorKind::WouldBlock {
                        Ok(stream)
                    } else {
                        Err(SslError::StreamError(e))
                    }
                }
                e => Err(e),
                Error::WantRead(..) | Error::WantWrite(..) => Ok(stream),
                _ => Err(stream.make_old_error(ret)),
            }
        }
    }