diff --git a/SharpPcap/LibPcap/SendQueue.cs b/SharpPcap/LibPcap/SendQueue.cs
index 9d17bfab..6db1edc2 100644
--- a/SharpPcap/LibPcap/SendQueue.cs
+++ b/SharpPcap/LibPcap/SendQueue.cs
@@ -105,6 +105,27 @@ public int Transmit(PcapDevice device, bool synchronized)
return Transmit(device, (synchronized == true) ? SendQueueTransmitModes.Synchronized : SendQueueTransmitModes.Normal);
}
+ ///
+ /// Send a queue of raw packets to the network.
+ ///
+ ///
+ /// The device on which to send the queue
+ /// A
+ ///
+ ///
+ /// Should the timestamps be respected
+ ///
+ ///
+ /// transmission cancellation token
+ ///
+ ///
+ /// The number of bytes sent as an
+ ///
+ public int Transmit(PcapDevice device, bool synchronized, CancellationToken token)
+ {
+ return Transmit(device, (synchronized == true) ? SendQueueTransmitModes.Synchronized : SendQueueTransmitModes.Normal, token);
+ }
+
///
/// Send a queue of raw packets to the network.
///
@@ -119,6 +140,27 @@ public int Transmit(PcapDevice device, bool synchronized)
/// The number of bytes sent as an
///
public int Transmit(PcapDevice device, SendQueueTransmitModes transmitMode)
+ {
+ return Transmit(device, transmitMode, CancellationToken.None);
+ }
+
+ ///
+ /// Send a queue of raw packets to the network.
+ ///
+ ///
+ /// The device on which to send the queue
+ /// A
+ ///
+ ///
+ /// Should the timestamps be respected
+ ///
+ ///
+ /// transmission cancellation token
+ ///
+ ///
+ /// The number of bytes sent as an
+ ///
+ public int Transmit(PcapDevice device, SendQueueTransmitModes transmitMode, CancellationToken token)
{
if (buffer == null)
{
@@ -128,14 +170,14 @@ public int Transmit(PcapDevice device, SendQueueTransmitModes transmitMode)
{
throw new DeviceNotReadyException("Can't transmit queue, the pcap device is closed");
}
- if (IsHardwareAccelerated)
+ if (IsHardwareAccelerated && token == CancellationToken.None)
{
return NativeTransmit(device, transmitMode);
}
- return ManagedTransmit(device, transmitMode);
+ return ManagedTransmit(device, transmitMode, token);
}
- protected unsafe int ManagedTransmit(PcapDevice device, SendQueueTransmitModes transmitMode)
+ protected unsafe int ManagedTransmit(PcapDevice device, SendQueueTransmitModes transmitMode, CancellationToken token)
{
if (CurrentLength == 0)
{
@@ -148,7 +190,7 @@ protected unsafe int ManagedTransmit(PcapDevice device, SendQueueTransmitModes t
{
var bufPtr = new IntPtr(buf);
var firstTimestamp = TimeSpan.FromTicks(PcapHeader.FromPointer(bufPtr, TimeResolution).Timeval.Date.Ticks);
- while (position < CurrentLength)
+ while ((position < CurrentLength) && (!token.IsCancellationRequested))
{
// Extract packet from buffer
var header = PcapHeader.FromPointer(bufPtr + position, TimeResolution);
diff --git a/Test/SendQueueTest.cs b/Test/SendQueueTest.cs
index 62fb297c..e5a33048 100644
--- a/Test/SendQueueTest.cs
+++ b/Test/SendQueueTest.cs
@@ -11,6 +11,8 @@
using System.Linq;
using static Test.TestHelper;
using static System.TimeSpan;
+using System.Threading;
+using System.Threading.Tasks;
namespace Test
{
@@ -285,9 +287,9 @@ public SendQueueWrapper(int memSize) : base(memSize)
return base.NativeTransmit(device, transmitMode);
}
- internal new int ManagedTransmit(PcapDevice device, SendQueueTransmitModes transmitMode)
+ internal int ManagedTransmit(PcapDevice device, SendQueueTransmitModes transmitMode)
{
- return base.ManagedTransmit(device, transmitMode);
+ return base.ManagedTransmit(device, transmitMode, CancellationToken.None);
}
}
@@ -302,7 +304,31 @@ public void Cleanup()
{
TestHelper.ConfirmIdleState();
}
- }
-
+ [TestCase(true)]
+ [TestCase(false)]
+ [Author("Andreas Amereller ")]
+ [Retry(3)]
+ public void TestCancelSending(bool synchronized)
+ {
+ var queue = new SendQueue(1024*1024*64);
+ int packages = 0;
+ while (queue.Add(EthernetPacket.RandomPacket()))
+ {
+ packages++;
+ }
+ var canceller = new CancellationTokenSource();
+ int packagesSent = 0;
+ using (var testInterface = TestHelper.GetPcapDevice())
+ {
+ testInterface.Open();
+ var snd = new Task(() => { packagesSent = queue.Transmit(testInterface, synchronized, canceller.Token); } );
+ snd.Start();
+ Thread.Sleep(100);
+ canceller.Cancel();
+ snd.Wait();
+ }
+ Assert.That(packagesSent < packages);
+ }
+ }
}