-
Notifications
You must be signed in to change notification settings - Fork 101
Description
Hi,
It would be nice to be able to run this in a thread.
Right now, if I call run() or run_socket() in a thread (daemon or otherwise), the process deadlocks when I call the unbind() method. Omitting the unbind() method "works" but doesn't seem like a clean solution.
Using the non-blocking functionality of the run() method via the optional block argument only allows polling. This is inefficient because instead of waiting on netfilter queue I/O most of the time, the script would be waiting on its polling timer most of the time which would increase delay.
My work-around is to set a timeout on the socket and poll a stop flag whenever a timeout occurs:
def nfq_threadproc():
while not stop:
try:
nfqueue.run_socket(s)
except socket.timeout:
pass
nfqueue = NetfilterQueue()
nfqueue.bind(1, handle_pkt) # Definition omitted for brevity
s = socket.fromfd(nfqueue.get_fd(), socket.AF_UNIX, socket.SOCK_STREAM) # Taken the from example code
s.settimeout(1)
stop = False
t = threading.Thread(target=nfq_threadproc)
t.start()
time.sleep(5) # Do something else here
stop = True
t.join()
It would be nice if this library used multiplexed I/O to efficiently permit threaded operation. This would entail using something like the select() library call (or something more modern like epoll(), at a cost to backward compatibility) instead of recv(). The interface could allow the user to specify the timeout interval via an optional run()/run_socket() argument or a new setter method. It could then check a flag at each iteration that would be set by the unbind() method to determine when another thread has initiated shutdown of the queue.
Let me know if I'm missing an easier way to accomplish my goal. Otherwise, I’d be happy to write up a gist or try my hand at a pull request for this if you agree it is a deficiency and is worth addressing.