]>
git.proxmox.com Git - pve-lxc-syscalld.git/blob - src/client.rs
5 use crate::lxcseccomp
::ProxyMessageBuffer
;
6 use crate::socket
::AsyncSeqPacketSocket
;
7 use crate::syscall
::SyscallStatus
;
10 socket
: AsyncSeqPacketSocket
,
14 pub fn new(socket
: AsyncSeqPacketSocket
) -> Arc
<Self> {
15 Arc
::new(Self { socket }
)
18 /// Wrap futures returning a `Result` so if they fail we `shutdown()` the socket to drop the
20 async
fn wrap_error
<F
>(self: Arc
<Self>, fut
: F
)
22 F
: std
::future
::Future
<Output
= Result
<(), Error
>>,
24 if let Err(err
) = fut
.await
{
25 eprintln
!("client error, dropping connection: {}", err
);
26 if let Err(err
) = self.socket
.shutdown(nix
::sys
::socket
::Shutdown
::Both
) {
27 eprintln
!(" (error shutting down client socket: {})", err
);
32 pub async
fn main(self: Arc
<Self>) {
33 self.clone().wrap_error(self.main_do()).await
36 async
fn main_do(self: Arc
<Self>) -> Result
<(), Error
> {
38 let mut msg
= ProxyMessageBuffer
::new(64);
40 if !msg
.recv(&self.socket
).await?
{
41 eprintln
!("client disconnected");
45 // Note: our spawned tasks here must not access our socket, as we cannot guarantee
46 // they'll be woken up if another task errors into `wrap_error()`.
47 tokio
::spawn(self.clone().wrap_error(self.clone().__handle_syscall(msg
)));
51 // Note: we must not use the socket for anything other than sending the result!
52 async
fn __handle_syscall(self: Arc
<Self>, mut msg
: ProxyMessageBuffer
) -> Result
<(), Error
> {
53 let result
= match Self::handle_syscall(&msg
).await
{
56 if let Some(errno
) = err
.downcast_ref
::<nix
::errno
::Errno
>() {
57 SyscallStatus
::Err(*errno
as _
)
58 } else if let Some(nix
::Error
::Sys(errno
)) = err
.downcast_ref
::<nix
::Error
>() {
59 SyscallStatus
::Err(*errno
as _
)
60 } else if let Some(ioerr
) = err
.downcast_ref
::<std
::io
::Error
>() {
61 if let Some(errno
) = ioerr
.raw_os_error() {
62 SyscallStatus
::Err(errno
)
72 let resp
= msg
.response_mut();
74 SyscallStatus
::Ok(val
) => {
78 SyscallStatus
::Err(err
) => {
84 msg
.respond(&self.socket
).await
.map_err(Error
::from
)
87 async
fn handle_syscall(msg
: &ProxyMessageBuffer
) -> Result
<SyscallStatus
, Error
> {
88 match msg
.request().data
.nr
as i64 {
89 libc
::SYS_mknod
=> crate::sys_mknod
::mknod(msg
).await
,
90 libc
::SYS_mknodat
=> crate::sys_mknod
::mknodat(msg
).await
,
91 _
=> Ok(SyscallStatus
::Err(libc
::ENOSYS
)),