]> git.proxmox.com Git - pve-lxc-syscalld.git/blob - src/main.rs
use Arc<> for clients
[pve-lxc-syscalld.git] / src / main.rs
1 #![feature(async_await)]
2
3 use std::ffi::OsString;
4 use std::io;
5 use std::sync::Arc;
6
7 use failure::{bail, format_err, Error};
8 use nix::sys::socket::SockAddr;
9
10 pub mod lxcseccomp;
11 pub mod seccomp;
12 pub mod socket;
13 pub mod tools;
14
15 use socket::{AsyncSeqPacketSocket, SeqPacketListener};
16
17 fn main() {
18 if let Err(err) = run() {
19 eprintln!("error: {}", err);
20 std::process::exit(1);
21 }
22 }
23
24 fn run() -> Result<(), Error> {
25 let socket_path = std::env::args_os()
26 .skip(1)
27 .next()
28 .ok_or_else(|| format_err!("missing parameter: socket path to listen on"))?;
29
30 match std::fs::remove_file(&socket_path) {
31 Ok(_) => (),
32 Err(ref e) if e.kind() == io::ErrorKind::NotFound => (), // Ok
33 Err(e) => bail!("failed to remove previous socket: {}", e),
34 }
35
36 tokio::run(async_run(socket_path));
37
38 Ok(())
39 }
40
41 async fn async_run(socket_path: OsString) {
42 if let Err(err) = async_run_do(socket_path).await {
43 eprintln!("error accepting clients, bailing out: {}", err);
44 }
45 }
46
47 async fn async_run_do(socket_path: OsString) -> Result<(), Error> {
48 let address =
49 SockAddr::new_unix(socket_path.as_os_str()).expect("cannot create struct sockaddr_un?");
50
51 let mut listener = SeqPacketListener::bind(&address)
52 .map_err(|e| format_err!("failed to create listening socket: {}", e))?;
53 loop {
54 let client = listener.accept().await?;
55 tokio::spawn(handle_client(Arc::new(client)));
56 }
57 }
58
59 async fn handle_client(client: Arc<AsyncSeqPacketSocket>) {
60 if let Err(err) = handle_client_do(client).await {
61 eprintln!(
62 "error communicating with client, dropping connection: {}",
63 err
64 );
65 }
66 }
67
68 async fn handle_client_do(client: Arc<AsyncSeqPacketSocket>) -> Result<(), Error> {
69 let mut msgbuf = lxcseccomp::ProxyMessageBuffer::new(64)
70 .map_err(|e| format_err!("failed to allocate proxy message buffer: {}", e))?;
71
72 loop {
73 let (size, _fds) = {
74 let mut iovec = msgbuf.io_vec_mut();
75 client.recv_fds_vectored(&mut iovec, 1).await?
76 };
77
78 if size == 0 {
79 println!("client disconnected");
80 break;
81 }
82
83 msgbuf.set_len(size)?;
84
85 let req = msgbuf.request();
86 println!("Received request for syscall {}", req.data.nr);
87
88 let resp = msgbuf.response_mut();
89 resp.val = 0;
90 resp.error = -libc::ENOENT;
91
92 let iovec = msgbuf.io_vec_no_cookie();
93 client.sendmsg_vectored(&iovec).await?;
94 }
95
96 Ok(())
97 }