]> git.proxmox.com Git - pve-lxc-syscalld.git/blame - src/client.rs
update to nix 0.24
[pve-lxc-syscalld.git] / src / client.rs
CommitLineData
e420f6f9
WB
1use std::sync::Arc;
2
8150a439 3use anyhow::Error;
f4b5a72f 4use nix::errno::Errno;
e420f6f9 5
8dd26985 6use crate::io::seq_packet::SeqPacketSocket;
e420f6f9 7use crate::lxcseccomp::ProxyMessageBuffer;
f4b5a72f 8use crate::syscall::{self, Syscall, SyscallStatus};
e420f6f9
WB
9
10pub struct Client {
9aa2a15a 11 socket: SeqPacketSocket,
e420f6f9
WB
12}
13
14impl Client {
9aa2a15a 15 pub fn new(socket: SeqPacketSocket) -> Arc<Self> {
e420f6f9
WB
16 Arc::new(Self { socket })
17 }
18
0e2d0fa2 19 /// Wrap futures returning a `Result` so if they fail we `shutdown()` the socket to drop the
e420f6f9
WB
20 /// client.
21 async fn wrap_error<F>(self: Arc<Self>, fut: F)
22 where
23 F: std::future::Future<Output = Result<(), Error>>,
24 {
25 if let Err(err) = fut.await {
26 eprintln!("client error, dropping connection: {}", err);
27 if let Err(err) = self.socket.shutdown(nix::sys::socket::Shutdown::Both) {
28 eprintln!(" (error shutting down client socket: {})", err);
29 }
30 }
31 }
32
33 pub async fn main(self: Arc<Self>) {
34 self.clone().wrap_error(self.main_do()).await
35 }
36
37 async fn main_do(self: Arc<Self>) -> Result<(), Error> {
7b37bdac 38 let mut msg = ProxyMessageBuffer::new(64);
e420f6f9 39 loop {
41214ae2 40 if !msg.recv(&self.socket).await? {
41214ae2
WB
41 break Ok(());
42 }
e420f6f9 43
7b37bdac 44 self.handle_syscall(&mut msg).await?;
e420f6f9
WB
45 }
46 }
47
7b37bdac 48 async fn handle_syscall(&self, msg: &mut ProxyMessageBuffer) -> Result<(), Error> {
a03af34b 49 let result = match Self::handle_syscall_do(msg).await {
c95be5f6
WB
50 Ok(r) => r,
51 Err(err) => {
7b37bdac 52 // handle the various kinds of errors we may get:
b8cb8723 53 if let Some(errno) = err.downcast_ref::<nix::Error>() {
c95be5f6
WB
54 SyscallStatus::Err(*errno as _)
55 } else if let Some(ioerr) = err.downcast_ref::<std::io::Error>() {
56 if let Some(errno) = ioerr.raw_os_error() {
57 SyscallStatus::Err(errno)
58 } else {
59 return Err(err);
60 }
61 } else {
62 return Err(err);
63 }
64 }
65 };
e420f6f9
WB
66
67 let resp = msg.response_mut();
68 match result {
69 SyscallStatus::Ok(val) => {
70 resp.val = val;
71 resp.error = 0;
72 }
73 SyscallStatus::Err(err) => {
74 resp.val = -1;
75 resp.error = -err;
76 }
77 }
78
0e2d0fa2 79 msg.respond(&self.socket).await.map_err(Error::from)
e420f6f9
WB
80 }
81
7b37bdac 82 async fn handle_syscall_do(msg: &ProxyMessageBuffer) -> Result<SyscallStatus, Error> {
f4b5a72f
WB
83 let (arch, sysnr) = (msg.request().data.arch, msg.request().data.nr);
84
85 let syscall_nr = match syscall::translate_syscall(arch, sysnr) {
86 Some(nr) => nr,
87 None => return Ok(Errno::ENOSYS.into()),
88 };
89
90 match syscall_nr {
91 Syscall::Mknod => crate::sys_mknod::mknod(msg).await,
92 Syscall::MknodAt => crate::sys_mknod::mknodat(msg).await,
d0e7b466 93 Syscall::Quotactl => crate::sys_quotactl::quotactl(msg).await,
e420f6f9
WB
94 }
95 }
96}