aboutsummaryrefslogtreecommitdiffstats
path: root/pcap-linux.c
diff options
context:
space:
mode:
authorGuy Harris <gharris@steve.local>2009-07-15 13:16:36 -0700
committerGuy Harris <gharris@steve.local>2009-07-15 13:16:36 -0700
commitf27e3da5479bcdabf8824d98c2d57160ce1ac039 (patch)
treeac3c8e46047e6642c1d5e50507ac6ee91dcf28f3 /pcap-linux.c
parent32c168dad42e24a3bcd246253358ed750334c376 (diff)
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%
Diffstat (limited to 'pcap-linux.c')
-rw-r--r--pcap-linux.c22
1 files changed, 16 insertions, 6 deletions
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) {