mirror of
https://github.com/samba-team/samba.git
synced 2025-01-03 01:18:10 +03:00
Properly handle read/write from the client socket
Signed-off-by: David Mulder <dmulder@samba.org> Reviewed-by: Alexander Bokovoy <ab@samba.org>
This commit is contained in:
parent
6907508cdb
commit
0bcc209d94
2
rust/Cargo.lock
generated
2
rust/Cargo.lock
generated
@ -2016,6 +2016,8 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
|||||||
name = "sock"
|
name = "sock"
|
||||||
version = "4.21.0"
|
version = "4.21.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chelps",
|
||||||
|
"dbg",
|
||||||
"libc",
|
"libc",
|
||||||
"libnss",
|
"libnss",
|
||||||
"ntstatus_gen",
|
"ntstatus_gen",
|
||||||
|
@ -6,6 +6,8 @@ homepage.workspace = true
|
|||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
chelps.workspace = true
|
||||||
|
dbg.workspace = true
|
||||||
libc.workspace = true
|
libc.workspace = true
|
||||||
libnss = "0.8.0"
|
libnss = "0.8.0"
|
||||||
ntstatus_gen.workspace = true
|
ntstatus_gen.workspace = true
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
mod proto;
|
mod proto;
|
||||||
pub use proto::*;
|
pub use proto::*;
|
||||||
|
|
||||||
|
use dbg::DBG_ERR;
|
||||||
use ntstatus_gen::*;
|
use ntstatus_gen::*;
|
||||||
use param::LoadParm;
|
use param::LoadParm;
|
||||||
use serde_json::{from_slice as json_from_slice, to_vec as json_to_vec};
|
use serde_json::{from_slice as json_from_slice, to_vec as json_to_vec};
|
||||||
@ -29,7 +30,7 @@ use std::error::Error;
|
|||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::time::Duration;
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
pub struct ClientStream {
|
pub struct ClientStream {
|
||||||
stream: UnixStream,
|
stream: UnixStream,
|
||||||
@ -38,7 +39,13 @@ pub struct ClientStream {
|
|||||||
impl ClientStream {
|
impl ClientStream {
|
||||||
pub fn new(path: &str) -> Result<Self, Box<dyn Error>> {
|
pub fn new(path: &str) -> Result<Self, Box<dyn Error>> {
|
||||||
Ok(ClientStream {
|
Ok(ClientStream {
|
||||||
stream: UnixStream::connect(path)?,
|
stream: UnixStream::connect(path)
|
||||||
|
.map_err(|e| {
|
||||||
|
DBG_ERR!("Unix socket stream setup error while connecting to {}: {:?}",
|
||||||
|
path, e
|
||||||
|
);
|
||||||
|
e
|
||||||
|
})?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,14 +54,64 @@ impl ClientStream {
|
|||||||
req: &Request,
|
req: &Request,
|
||||||
timeout: u64,
|
timeout: u64,
|
||||||
) -> Result<Response, Box<dyn Error>> {
|
) -> Result<Response, Box<dyn Error>> {
|
||||||
|
// Set the timeout
|
||||||
let timeout = Duration::from_secs(timeout);
|
let timeout = Duration::from_secs(timeout);
|
||||||
self.stream.set_read_timeout(Some(timeout))?;
|
self.stream.set_read_timeout(Some(timeout))?;
|
||||||
self.stream.set_write_timeout(Some(timeout))?;
|
self.stream.set_write_timeout(Some(timeout))?;
|
||||||
|
|
||||||
|
// Encode the request as bytes
|
||||||
let req_bytes = json_to_vec(req)?;
|
let req_bytes = json_to_vec(req)?;
|
||||||
|
|
||||||
|
// Send the request
|
||||||
self.stream.write_all(&req_bytes)?;
|
self.stream.write_all(&req_bytes)?;
|
||||||
let mut buf = Vec::new();
|
|
||||||
self.stream.read_to_end(&mut buf)?;
|
// Now wait on the response
|
||||||
let resp: Response = json_from_slice(&buf)?;
|
let start = SystemTime::now();
|
||||||
|
let mut read_started = false;
|
||||||
|
let mut data = Vec::with_capacity(1024);
|
||||||
|
let mut counter = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut buffer = [0; 1024];
|
||||||
|
let durr =
|
||||||
|
SystemTime::now().duration_since(start).map_err(Box::new)?;
|
||||||
|
if durr > timeout {
|
||||||
|
DBG_ERR!("Socket timeout");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
match self.stream.read(&mut buffer) {
|
||||||
|
Ok(0) => {
|
||||||
|
if read_started {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(count) => {
|
||||||
|
data.extend_from_slice(&buffer);
|
||||||
|
counter += count;
|
||||||
|
if count == 1024 {
|
||||||
|
read_started = true;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
DBG_ERR!(
|
||||||
|
"Stream read failure from {:?}: {:?}",
|
||||||
|
&self.stream,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return Err(Box::new(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.truncate(counter);
|
||||||
|
|
||||||
|
// Now decode the response
|
||||||
|
let resp: Response = json_from_slice(data.as_slice())?;
|
||||||
Ok(resp)
|
Ok(resp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user