Skip to content

Commit 56b9ede

Browse files
committed
fix bio
1 parent f896d0d commit 56b9ede

File tree

2 files changed

+39
-36
lines changed

2 files changed

+39
-36
lines changed

common/src/fileutils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ pub fn fopen(path: &std::path::Path, mode: &str) -> std::io::Result<*mut libc::F
494494

495495
#[cfg(not(windows))]
496496
{
497-
use std::os::unix::io::IntoRawFd;
497+
use std::os::fd::IntoRawFd;
498498

499499
// Convert File to raw fd
500500
let fd = file.into_raw_fd();

stdlib/src/ssl.rs

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,20 +1632,7 @@ mod _ssl {
16321632
}
16331633
}
16341634

1635-
// Set BIOs using SSL_set_bio
1636-
// BIOs are reference counted and SSL_set_bio borrows our reference
1637-
// To prevent double free, we need to increment the reference count
1638-
unsafe {
1639-
let inbio_ptr = args.incoming.bio;
1640-
let outbio_ptr = args.outgoing.bio;
1641-
1642-
// Increment reference counts
1643-
BIO_up_ref(inbio_ptr);
1644-
BIO_up_ref(outbio_ptr);
1645-
1646-
// Set BIOs on SSL object
1647-
sys::SSL_set_bio(ssl.as_ptr(), inbio_ptr, outbio_ptr);
1648-
}
1635+
// Don't use SSL_set_bio - let SslStream drive I/O through BioStream Read/Write
16491636

16501637
// Configure post-handshake authentication (PHA)
16511638
#[cfg(ossl111)]
@@ -1672,8 +1659,8 @@ mod _ssl {
16721659

16731660
// Create a BioStream wrapper (dummy, actual IO goes through BIOs)
16741661
let bio_stream = BioStream {
1675-
_inbio: args.incoming,
1676-
_outbio: args.outgoing,
1662+
inbio: args.incoming,
1663+
outbio: args.outgoing,
16771664
};
16781665

16791666
// Create SslStream with BioStream
@@ -1841,32 +1828,51 @@ mod _ssl {
18411828

18421829
// BIO stream wrapper to implement Read/Write traits for MemoryBIO
18431830
struct BioStream {
1844-
_inbio: PyRef<PySslMemoryBio>,
1845-
_outbio: PyRef<PySslMemoryBio>,
1831+
inbio: PyRef<PySslMemoryBio>,
1832+
outbio: PyRef<PySslMemoryBio>,
18461833
}
18471834

18481835
impl Read for BioStream {
1849-
fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> {
1850-
// BIO mode doesn't use actual IO - data is transferred via MemoryBIO
1851-
// This should never be called as SSL will directly use the BIOs
1852-
Err(std::io::Error::new(
1853-
std::io::ErrorKind::Unsupported,
1854-
"BIO mode doesn't support direct read",
1855-
))
1836+
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
1837+
// Read from incoming MemoryBIO
1838+
unsafe {
1839+
let nbytes = sys::BIO_read(
1840+
self.inbio.bio,
1841+
buf.as_mut_ptr() as *mut _,
1842+
buf.len().min(i32::MAX as usize) as i32,
1843+
);
1844+
if nbytes < 0 {
1845+
// BIO_read returns -1 on error or when no data is available
1846+
// Check if it's a retry condition (WANT_READ)
1847+
Err(std::io::Error::new(
1848+
std::io::ErrorKind::WouldBlock,
1849+
"BIO has no data available",
1850+
))
1851+
} else {
1852+
Ok(nbytes as usize)
1853+
}
1854+
}
18561855
}
18571856
}
18581857

18591858
impl Write for BioStream {
1860-
fn write(&mut self, _buf: &[u8]) -> std::io::Result<usize> {
1861-
// BIO mode doesn't use actual IO - data is transferred via MemoryBIO
1862-
// This should never be called as SSL will directly use the BIOs
1863-
Err(std::io::Error::new(
1864-
std::io::ErrorKind::Unsupported,
1865-
"BIO mode doesn't support direct write",
1866-
))
1859+
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
1860+
// Write to outgoing MemoryBIO
1861+
unsafe {
1862+
let nbytes = sys::BIO_write(
1863+
self.outbio.bio,
1864+
buf.as_ptr() as *const _,
1865+
buf.len().min(i32::MAX as usize) as i32,
1866+
);
1867+
if nbytes < 0 {
1868+
return Err(std::io::Error::other("BIO write failed"));
1869+
}
1870+
Ok(nbytes as usize)
1871+
}
18671872
}
18681873

18691874
fn flush(&mut self) -> std::io::Result<()> {
1875+
// MemoryBIO doesn't need flushing
18701876
Ok(())
18711877
}
18721878
}
@@ -2663,9 +2669,6 @@ mod _ssl {
26632669
unsafe extern "C" {
26642670
// X509_check_ca returns 1 for CA certificates, 0 otherwise
26652671
fn X509_check_ca(x: *const sys::X509) -> libc::c_int;
2666-
2667-
// BIO_up_ref increments the reference count of a BIO
2668-
fn BIO_up_ref(bio: *mut sys::BIO) -> libc::c_int;
26692672
}
26702673

26712674
unsafe extern "C" {

0 commit comments

Comments
 (0)