aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <gharris@sonic.net>2022-12-07 23:40:27 -0800
committerGuy Harris <gharris@sonic.net>2022-12-07 23:41:15 -0800
commit8ae5c3e4ccc7b800934e5ec0d1b3037353628303 (patch)
tree30094406ad74e979c84fc68d56a8c3179e3a2a35
parent0a16fcce0646a328965237cc8475dd60978b7928 (diff)
downloadlibpcap-8ae5c3e4ccc7b800934e5ec0d1b3037353628303.tar.gz
pcap_breakloop(3PCAP): describe the shiny new world. [skip ci]
Note that, on Linux and Windows, pcap_breakloop() attempts to force a wakeup on the thread reading the packets. Note all the hilarity that ensues from that; this is one of the areas where capture-mechanism differences are not quite so easily papered over. (These capture mechanisms were all pretty much designed for a program that reads captures until it's told to stop, and then may or may not process packets that arrived after that point. Making it available through libpcap has opened up packet capturing to a zillion developers, many of whom are doing different types of capture programs with different requirements, and stumbling over all these problems. Perhaps it's time for a rethink. We won't even mention the use of the capture mechanisms for purposes *other* than packet capture, such as implementing various protocols atop the link-layer; libpcap's API is not the best fit for that - a corss-platform "link-layer sockets" library, possibly using a *different* OS mechanism than libpcap on some platforms, might be handy there.) (cherry picked from commit 6795eae85bd54980c78c085591bafe7436bae174)
-rw-r--r--pcap_breakloop.3pcap66
1 files changed, 46 insertions, 20 deletions
diff --git a/pcap_breakloop.3pcap b/pcap_breakloop.3pcap
index 996290f9..f2fc6e80 100644
--- a/pcap_breakloop.3pcap
+++ b/pcap_breakloop.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_BREAKLOOP 3PCAP "25 July 2018"
+.TH PCAP_BREAKLOOP 3PCAP "7 December 2022"
.SH NAME
pcap_breakloop \- force a pcap_dispatch() or pcap_loop() call to return
.SH SYNOPSIS
@@ -39,11 +39,23 @@ or
to return rather than looping; they will return the number of packets
that have been processed so far, or
.B PCAP_ERROR_BREAK
-if no packets have been processed so far.
+if no packets have been processed so far. If the loop is currently
+blocked waiting for packets to arrive,
+.BR pcap_breakloop ()
+will also, on some platforms, wake up the thread that is blocked. In
+this version of libpcap, the only platforms on which a wakeup is caused
+by
+.BR pcap_breakloop ()
+are Linux and Windows, and the wakeup will only be caused when capturing
+on network interfaces; it will not be caused on other operating systems,
+and will not be caused on any OS when capturing on other types of
+devices.
.PP
This routine is safe to use inside a signal handler on UNIX or a console
-control handler on Windows, as it merely sets a flag that is checked
-within the loop.
+control handler on Windows, or in a thread other than the one in which
+the loop is running, as it merely sets a flag that is checked within the
+loop and, on some platforms, performs a signal-safe and thread-safe API
+call.
.PP
The flag is checked in loops reading packets from the OS - a signal by
itself will not necessarily terminate those loops - as well as in loops
@@ -61,23 +73,37 @@ packets arrive and the call completes.
.PP
.ft B
Note also that, in a multi-threaded application, if one thread is
-blocked in pcap_dispatch(), pcap_loop(), pcap_next(3PCAP), or pcap_next_ex(3PCAP),
-a call to pcap_breakloop() in a different thread will not unblock that
-thread.
+blocked in pcap_dispatch(), pcap_loop(), pcap_next(3PCAP), or
+pcap_next_ex(3PCAP), a call to pcap_breakloop() in a different thread
+will only unblock that thread on the platforms and capture devices
+listed above.
+.PP
+If a non-zero packet buffer timeout is set on the
+.BR pcap_t ,
+and you are capturing on a network interface, the thread will be
+unblocked with the timeout expires. This is not guaranteed to happen
+unless at least one packet has arrived; the only platforms on which it
+happens are macOS, the BSDs, Solaris 11, AIX, Tru64 UNIX, and Windows.
+.PP
+If you want to ensure that the loop will eventually be unblocked on any
+other platforms, or unblocked when capturing on a device other than a
+network interface, you will need to use whatever mechanism the OS
+provides for breaking a thread out of blocking calls in order to unblock
+the thread, such as thread cancellation or thread signalling in systems
+that support POSIX threads.
.ft R
-You will need to use whatever mechanism the OS provides for
-breaking a thread out of blocking calls in order to unblock the thread,
-such as thread cancellation or thread signalling in systems that support
-POSIX threads, or
-.BR SetEvent ()
-on the result of
-.BR pcap_getevent ()
-on a
-.B pcap_t
-on which the thread is blocked on Windows. Asynchronous procedure calls
-will not work on Windows, as a thread blocked on a
-.B pcap_t
-will not be in an alertable state.
+.PP
+.ft B
+Note that if pcap_breakloop() unblocks the thread capturing packets, and
+you are running on a platform that supports packet buffering, there may
+be packets in the buffer that arrived before pcap_breakloop() were
+called but that weren't yet provided to libpcap, those packets will not
+have been processed by pcap_dispatch() or pcap_loop(). If
+pcap_breakloop() was called in order to terminate the capture process,
+then, in order to process those packets, you would have to call
+pcap_dispatch() one time in order to process the last batch of packets.
+This may block until the packet buffer timeout expires, so a non-zero
+packet buffer timeout must be used.
.ft R
.PP
Note that