Added recv skip of ENOBUFS, also set of rcv socklen

This commit is contained in:
Dave Benson 2015-08-06 16:26:40 -04:00
parent 53a55fd588
commit f4e3f0936d
3 changed files with 2977 additions and 2554 deletions

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,13 @@ cdef extern from "sys/types.h":
ctypedef unsigned short int u_int16_t
ctypedef unsigned int u_int32_t
cdef extern from "<errno.h>":
int errno
# dummy defines from asm-generic/errno.h:
cdef enum:
ENOBUFS = 105 # No buffer space available
cdef extern from "netinet/ip.h":
struct iphdr:
u_int8_t tos
@ -69,6 +76,11 @@ cdef extern from "libnfnetlink/linux_nfnetlink.h":
u_int8_t version
u_int16_t res_id
cdef extern from "libnfnetlink/libnfnetlink.h":
struct nfnl_handle:
pass
unsigned int nfnl_rcvbufsiz(nfnl_handle *h, unsigned int size)
cdef extern from "libnetfilter_queue/linux_nfnetlink_queue.h":
enum nfqnl_config_mode:
NFQNL_COPY_NONE
@ -130,6 +142,7 @@ cdef extern from "libnetfilter_queue/libnetfilter_queue.h":
int nfq_get_timestamp(nfq_data *nfad, timeval *tv)
nfqnl_msg_packet_hw *nfq_get_packet_hw(nfq_data *nfad)
int nfq_get_nfmark (nfq_data *nfad)
nfnl_handle *nfq_nfnlh(nfq_handle *h)
# Dummy defines from linux/socket.h:
cdef enum: # Protocol families, same as address families.

View File

@ -12,13 +12,17 @@ COPY_NONE = 1
COPY_META = 2
COPY_PACKET = 3
DEFAULT_MAX_QUEUELEN = 1024
# Packet copying defaults
DEF DEFAULT_MAX_QUEUELEN = 1024
DEF MaxPacketSize = 0xFFFF
DEF BufferSize = 4096
DEF MetadataSize = 80
DEF MaxCopySize = BufferSize - MetadataSize
# Experimentally determined overhead
DEF SockOverhead = 760+20
DEF SockCopySize = MaxCopySize + SockOverhead
# Socket queue should hold max number of packets of copysize bytes
DEF SockRcvSize = DEFAULT_MAX_QUEUELEN * SockCopySize / 2
cdef int global_callback(nfq_q_handle *qh, nfgenmsg *nfmsg,
nfq_data *nfa, void *data) with gil:
@ -151,8 +155,10 @@ cdef class NetfilterQueue:
def bind(self, int queue_num, object user_callback,
u_int32_t max_len=DEFAULT_MAX_QUEUELEN,
u_int8_t mode=NFQNL_COPY_PACKET,
u_int32_t range=MaxPacketSize):
u_int32_t range=MaxPacketSize,
u_int32_t sock_len=SockRcvSize):
"""Create and bind to a new queue."""
cdef unsigned int newsiz
self.user_callback = user_callback
self.qh = nfq_create_queue(self.h, queue_num,
<nfq_callback*>global_callback, <void*>self)
@ -165,6 +171,10 @@ cdef class NetfilterQueue:
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:
raise RuntimeWarning("Socket rcvbuf limit is now %d, requested %d." % (newsiz,sock_len))
def unbind(self):
"""Destroy the queue."""
@ -177,12 +187,14 @@ cdef class NetfilterQueue:
cdef int fd = nfq_fd(self.h)
cdef char buf[BufferSize]
cdef int rv
with nogil:
rv = recv(fd, buf, sizeof(buf), 0)
while rv >= 0:
nfq_handle_packet(self.h, buf, rv)
while True:
with nogil:
rv = recv(fd, buf, sizeof(buf), 0)
if (rv >= 0):
nfq_handle_packet(self.h, buf, rv)
else:
if errno != ENOBUFS:
break
PROTOCOLS = {
0: "HOPOPT",