From f27e3da5479bcdabf8824d98c2d57160ce1ac039 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Wed, 15 Jul 2009 13:16:36 -0700 Subject: From Dustin Spicuzza: - Fixed bug where create_ring would fail for particular snaplen and buffer size combinations - Changed ring allocation to retry with 5% less buffer size instead of 50% --- pcap-linux.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'pcap-linux.c') diff --git a/pcap-linux.c b/pcap-linux.c index b1a00ce..525d2f6 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -2600,19 +2600,29 @@ create_ring(pcap_t *handle) frames_per_block = req.tp_block_size/req.tp_frame_size; + /* ask the kernel to create the ring */ +retry: req.tp_block_nr = req.tp_frame_nr / frames_per_block; /* req.tp_frame_nr is requested to match frames_per_block*req.tp_block_nr */ req.tp_frame_nr = req.tp_block_nr * frames_per_block; - - /* ask the kernel to create the ring */ -retry: + if (setsockopt(handle->fd, SOL_PACKET, PACKET_RX_RING, (void *) &req, sizeof(req))) { - /* try to reduce requested ring size to prevent memory failure */ if ((errno == ENOMEM) && (req.tp_block_nr > 1)) { - req.tp_frame_nr >>= 1; - req.tp_block_nr = req.tp_frame_nr/frames_per_block; + /* + * Memory failure; try to reduce the requested ring + * size. + * + * We used to reduce this by half -- do 5% instead. + * That may result in more iterations and a longer + * startup, but the user will be much happier with + * the resulting buffer size. + */ + if (req.tp_frame_nr < 20) + req.tp_frame_nr -= 1; + else + req.tp_frame_nr -= req.tp_frame_nr/20; goto retry; } if (errno == ENOPROTOOPT) { -- cgit v1.2.3