Improve & test error handling

This commit is contained in:
Joshua Oreman 2022-01-11 22:01:53 -07:00
parent e7d451098b
commit 99c13b3d8f
5 changed files with 992 additions and 612 deletions

View File

@ -3,6 +3,9 @@ v0.9.0, unreleased
Add Packet.retain() to save the packet contents in such cases
Eliminate warnings during build on py3
Add CI and basic test suite
Raise a warning, not an error, if we don't get the bufsize we want
Don't allow bind() more than once on the same NetfilterQueue, since
that would leak the old queue handle
v0.8.1, 30 Jan 2017
Fix bug #25- crashing when used in OUTPUT or POSTROUTING chains

File diff suppressed because it is too large Load Diff

View File

@ -206,6 +206,9 @@ cdef class NetfilterQueue:
u_int32_t range=MaxPacketSize,
u_int32_t sock_len=SockRcvSize):
"""Create and bind to a new queue."""
if self.qh != NULL:
raise RuntimeError("A queue is already bound; use unbind() first")
cdef unsigned int newsiz
self.user_callback = user_callback
self.qh = nfq_create_queue(self.h, queue_num,
@ -216,18 +219,23 @@ cdef class NetfilterQueue:
if range > MaxCopySize:
range = MaxCopySize
if nfq_set_mode(self.qh, mode, range) < 0:
self.unbind()
raise OSError("Failed to set packet copy mode.")
nfq_set_queue_maxlen(self.qh, max_len)
newsiz = nfnl_rcvbufsiz(nfq_nfnlh(self.h), sock_len)
if newsiz != sock_len * 2:
warnings.warn_explicit(
"Socket rcvbuf limit is now %d, requested %d." % (newsiz, sock_len),
category=RuntimeWarning,
filename=__FILE__,
lineno=__LINE__,
)
try:
warnings.warn_explicit(
"Socket rcvbuf limit is now %d, requested %d." % (newsiz, sock_len),
category=RuntimeWarning,
filename=bytes(__FILE__).decode("ascii"),
lineno=__LINE__,
)
except: # if warnings are being treated as errors
self.unbind()
raise
def unbind(self):
"""Destroy the queue."""

View File

@ -220,7 +220,7 @@ class Harness:
else:
raise RuntimeError(
"Couldn't bind any netfilter queue number between 0-15"
)
) from last_error
try:
rule = f"-d {PEER_IP[idx]} -j NFQUEUE --queue-num {queue_num}"
await trio.run_process(f"/sbin/iptables -A FORWARD {rule}".split())

View File

@ -1,5 +1,6 @@
import struct
import trio
import pytest
async def test_comms_without_queue(harness):
@ -74,3 +75,21 @@ async def test_rewrite_reorder(harness):
nursery.start_soon(munge, p2)
await harness.send(2, b"one", b"two", b"three", b"four")
await harness.expect(2, b"numero uno", b"three", b"TWO", b"four")
async def test_errors(harness):
with pytest.warns(RuntimeWarning, match="rcvbuf limit is"):
async with harness.capture_packets_to(2, sock_len=2**30):
pass
async with harness.capture_packets_to(2, queue_num=0):
with pytest.raises(OSError, match="Failed to create queue"):
async with harness.capture_packets_to(2, queue_num=0):
pass
from netfilterqueue import NetfilterQueue
nfq = NetfilterQueue()
nfq.bind(1, lambda p: None)
with pytest.raises(RuntimeError, match="A queue is already bound"):
nfq.bind(2, lambda p: None)