From f27e3da5479bcdabf8824d98c2d57160ce1ac039 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Wed, 15 Jul 2009 13:16:36 -0700 Subject: [PATCH] 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% --- CREDITS | 1 + pcap-linux.c | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/CREDITS b/CREDITS index 723a5a6..5d0b376 100644 --- a/CREDITS +++ b/CREDITS @@ -32,6 +32,7 @@ Additional people who have contributed patches: Dean Gaudet Don Ebright Dug Song + Dustin Spicuzza Eric Anderson Erik de Castro Lopo Florent Drouin 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) {