nfq-rs icon indicating copy to clipboard operation
nfq-rs copied to clipboard

Add try_verdict method which doesn't consume the passed msg in case you need…

Open agalauner-r7 opened this issue 1 year ago • 0 comments

This patch adds a try_verdict method that only takes a reference to a Message and doesn't consume it.

I needed this, because I am wrapping a Queue object in an AsyncFd and set it to non-blocking. In case the write to issue the verdict fails with EWOULDBLOCK, the passed in Message is gone, because it is moved into the verdict method and I can't retry later.

The naming of try_verdict is debatable, but naming things is one of the hardest problems in computer science, I guess. I am open for better name suggestions.

Here is some code that I implemented to make a Queue async so that it's clearer why I need that new method:

use std::{fmt, io};

use nfq::{Message, Queue};
use tokio::io::unix::AsyncFd;

pub struct AsyncQueue {
    inner: AsyncFd<Queue>,
}

impl fmt::Debug for AsyncQueue {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("AsyncQueue").finish()
    }
}

impl AsyncQueue {
    pub fn new(mut queue: Queue) -> io::Result<Self> {
        queue.set_nonblocking(true);

        Ok(Self {
            inner: AsyncFd::new(queue).expect("Unable to create AsyncFd for nfqueue"),
        })
    }

    pub async fn recv(&mut self) -> io::Result<nfq::Message> {
        loop {
            let mut guard = self.inner.readable_mut().await?;

            match guard.try_io(|inner| inner.get_mut().recv()) {
                Ok(result) => return result,
                Err(_would_block) => continue,
            }
        }
    }

    pub async fn verdict(&mut self, msg: Message) -> io::Result<()> {
        loop {
            let mut guard = self.inner.writable_mut().await?;

            match guard.try_io(|inner| inner.get_mut().try_verdict(&msg)) {
                Ok(result) => return result,
                Err(_would_block) => continue,
            }
        }
    }
}

agalauner-r7 avatar Jan 13 '24 14:01 agalauner-r7