diff --git a/Machina.FFXIV/FFXIVNetworkMonitor.cs b/Machina.FFXIV/FFXIVNetworkMonitor.cs
index 228c3c5..76ee5eb 100644
--- a/Machina.FFXIV/FFXIVNetworkMonitor.cs
+++ b/Machina.FFXIV/FFXIVNetworkMonitor.cs
@@ -60,7 +60,7 @@ public Boolean UseSocketFilter
public delegate void MessageReceivedDelegate(string connection, long epoch, byte[] message);
///
- /// Specifies the delegate that is called when data is received and successfully decoded/
+ /// Specifies the delegate that is called when data is received and successfully decoded.
///
public MessageReceivedDelegate MessageReceived = null;
@@ -104,7 +104,7 @@ public void Start()
_monitor.WindowName = "FINAL FANTASY XIV";
_monitor.MonitorType = MonitorType;
_monitor.LocalIP = LocalIP;
- _monitor.UseOneSocketPerRemoteIP = UseSocketFilter;
+ _monitor.UseSocketFilter = UseSocketFilter;
_monitor.DataSent = (string connection, byte[] data) => ProcessSentMessage(connection, data);
_monitor.DataReceived = (string connection, byte[] data) => ProcessReceivedMessage(connection, data);
diff --git a/Machina.Tests/TCPNetworkMonitorTests.cs b/Machina.Tests/TCPNetworkMonitorTests.cs
index 98a3483..95944db 100644
--- a/Machina.Tests/TCPNetworkMonitorTests.cs
+++ b/Machina.Tests/TCPNetworkMonitorTests.cs
@@ -23,7 +23,7 @@ public void TCPNetworkMonitor_RawSocket_SendAndReceiveData()
monitor.MonitorType = TCPNetworkMonitor.NetworkMonitorType.RawSocket;
monitor.DataReceived += (string connection, byte[] data) => DataReceived(connection, data);
monitor.DataSent += (string connection, byte[] data) => DataSent(connection, data);
- monitor.UseOneSocketPerRemoteIP = false;
+ monitor.UseSocketFilter = false;
monitor.Start();
// start a dummy async download
diff --git a/Machina/Properties/AssemblyInfo.cs b/Machina/Properties/AssemblyInfo.cs
index afe37ce..0dbebfc 100644
--- a/Machina/Properties/AssemblyInfo.cs
+++ b/Machina/Properties/AssemblyInfo.cs
@@ -51,7 +51,7 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.0.1.0")]
+[assembly: AssemblyVersion("2.1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("2.0.1.0")]
+[assembly: AssemblyFileVersion("2.1.0.0")]
diff --git a/Machina/RawPCap.cs b/Machina/RawPCap.cs
index b3fe0ea..826ffeb 100644
--- a/Machina/RawPCap.cs
+++ b/Machina/RawPCap.cs
@@ -243,7 +243,14 @@ public void Destroy()
else
break;
- _thread.Abort();
+ try
+ {
+ if (_thread.IsAlive)
+ _thread.Abort();
+ }
+ catch (Exception)
+ {
+ }
_thread = null;
}
@@ -377,6 +384,8 @@ private void StartCapture(Device device, uint remoteAddress)
// Start thread
_thread = new Thread(new ThreadStart(RunCaptureLoop));
+ _thread.Name = "Machina.RawPCap.RunCaptureLoop";
+ _thread.IsBackground = true;
_thread.Start();
}
catch (Exception ex)
@@ -399,13 +408,15 @@ private void StartCapture(Device device, uint remoteAddress)
private unsafe void RunCaptureLoop()
{
- try
+ bool bExceptionLogged = false;
+
+ while (_cancelThread == false)
{
- while (_cancelThread == false)
+ try
{
if (_activeDevice == null)
{
- System.Threading.Thread.Sleep(100);
+ Thread.Sleep(100);
continue;
}
@@ -416,26 +427,30 @@ private unsafe void RunCaptureLoop()
// note: buffer returned by pcap_next_ex is static and owned by pcap library, does not need to be freed.
int status = pcap_next_ex(_activeDevice.Handle, ref packetHeaderPtr, ref packetDataPtr);
- if (status == 0)//500ms timeout
+ if (status == 0) // 500ms timeout
continue;
else if (status == -1) // error
{
- string error = "";// Marshal.PtrToStringAnsi(pcap_geterr(_activeDevice.Handle));
- Trace.Write("RawPCap: Error during pcap_loop. " + error);
+ string error = Marshal.PtrToStringAnsi(pcap_geterr(_activeDevice.Handle));
+ if (!bExceptionLogged)
+ Trace.WriteLine("RawPCap: Error during pcap_loop. " + error);
- System.Threading.Thread.Sleep(100);
- continue;
+ bExceptionLogged = true;
+
+ Thread.Sleep(100);
}
else if (status != 1) // anything else besides success
{
- Trace.Write("RawPCap: Unknown response code [" + status.ToString() + "] from pcap_next_ex.);");
- System.Threading.Thread.Sleep(100);
- continue;
+ if (!bExceptionLogged)
+ Trace.WriteLine("RawPCap: Unknown response code [" + status.ToString() + "] from pcap_next_ex.);");
+
+ bExceptionLogged = true;
+
+ Thread.Sleep(100);
}
else
{
pcap_pkthdr packetHeader = *(pcap_pkthdr*)packetHeaderPtr;
- //pcap_pkthdr packetHeader = (pcap_pkthdr)Marshal.PtrToStructure(packetHeaderPtr, typeof(pcap_pkthdr));
if (packetHeader.caplen <= layer2Length)
continue;
@@ -444,7 +459,7 @@ private unsafe void RunCaptureLoop()
// prepare data - skip the 14-byte ethernet header
buffer.AllocatedSize = (int)packetHeader.caplen - layer2Length;
if (buffer.AllocatedSize > buffer.Data.Length)
- Trace.Write("RawPCap: packet length too large: " + buffer.AllocatedSize.ToString());
+ Trace.WriteLine("RawPCap: packet length too large: " + buffer.AllocatedSize.ToString());
else
{
@@ -454,10 +469,21 @@ private unsafe void RunCaptureLoop()
}
}
}
- }
- catch (Exception ex)
- {
- Trace.WriteLine("WinPCap: Exception during RunCaptureLoop. " + ex.ToString());
+ catch (ThreadAbortException)
+ {
+ // do nothing, thread is aborting.
+ return;
+ }
+ catch (Exception ex)
+ {
+ if (!bExceptionLogged)
+ Trace.WriteLine("WinPCap: Exception during RunCaptureLoop. " + ex.ToString());
+
+ bExceptionLogged = true;
+
+ // add sleep
+ Thread.Sleep(100);
+ }
}
}
@@ -477,11 +503,11 @@ private unsafe void RunCaptureLoop()
// else if (status == -1)
// {
// string error = Marshal.PtrToStringAnsi(pcap_geterr(_activeDevice.Handle));
- // Trace.Write("RawPCap: Error during pcap_loop. " + error);
+ // Trace.WriteLine("RawPCap: Error during pcap_loop. " + error);
// }
// else
// {
- // Trace.Write("RawPCap: Unknown status result from pcap_loop [" + status.ToString() + "]. exiting.");
+ // Trace.WriteLine("RawPCap: Unknown status result from pcap_loop [" + status.ToString() + "]. exiting.");
// return;
// }
// }
diff --git a/Machina/RawSocket.cs b/Machina/RawSocket.cs
index 11ec8d6..d4ed68e 100644
--- a/Machina/RawSocket.cs
+++ b/Machina/RawSocket.cs
@@ -143,7 +143,7 @@ private static void OnReceive(IAsyncResult ar)
}
catch (Exception ex)
{
- Trace.Write("RawSocket: Error while receiving socket data. Network capture aborted, please restart application." + ex.ToString());
+ Trace.WriteLine("RawSocket: Error while receiving socket data. Network capture aborted, please restart application." + ex.ToString());
}
}
}
diff --git a/Machina/TCPNetworkMonitor.cs b/Machina/TCPNetworkMonitor.cs
index e6595a0..359dc2e 100644
--- a/Machina/TCPNetworkMonitor.cs
+++ b/Machina/TCPNetworkMonitor.cs
@@ -18,7 +18,7 @@ namespace Machina
/// supplied to distinguish between multiple connections from the same process.
/// DataSent: Delegate that is called when data is sent and successfully decoded through IP and TCP decoders. Note that a connection identifier is
/// supplied to distinguish between multiple connections from the same process.
- /// UseOneSocketPerRemoteIP: boolean that specifies whether to start data capture as connections are detected within the target process (new behavior), or monitor
+ /// UseSocketFilter: boolean that specifies whether to start data capture as connections are detected within the target process (new behavior), or monitor
/// the primary interface for the process and capture all data sent/received on that interface - and filter it. The new behavior may cause some data to be lost
/// on connection startup, but significantly reduces the filtering overhead caused by other traffic on the network interface.
///
@@ -59,7 +59,7 @@ public string LocalIP
public string WindowName
{ get; set; } = "";
- public bool UseOneSocketPerRemoteIP
+ public bool UseSocketFilter
{ get; set; } = false;
#region Data Delegates section
@@ -122,9 +122,10 @@ public void Start()
_processTCPInfo.ProcessID = ProcessID;
_processTCPInfo.ProcessWindowName = WindowName;
- _monitorThread = new Thread(new ThreadStart(Run));
- _monitorThread.Priority = ThreadPriority.Highest;
- _monitorThread.Start();
+ _monitorThread = new Thread(new ParameterizedThreadStart(Run));
+ _monitorThread.Name = "Machina.TCPNetworkMonitor.Start";
+ _monitorThread.IsBackground = true;
+ _monitorThread.Start(this);
}
///
@@ -135,19 +136,29 @@ public void Stop()
Abort = true;
if (_monitorThread != null)
{
- for (int i = 0; i < 50; i++)
- if (_monitorThread.IsAlive)
- System.Threading.Thread.Sleep(100);
- else
- break;
if (_monitorThread.IsAlive)
{
- _monitorThread.Abort();
+ for (int i = 0; i < 50; i++)
+ if (_monitorThread.IsAlive)
+ Thread.Sleep(10);
+ else
+ break;
+ }
+
+ try
+ {
+ if (_monitorThread.IsAlive)
+ _monitorThread.Abort();
+ }
+ catch (Exception)
+ {
}
+
_monitorThread = null;
}
Cleanup();
+ Abort = false;
}
private void Cleanup()
@@ -164,11 +175,11 @@ private void Cleanup()
_connections.Clear();
}
- private void Run()
+ private void Run(object state)
{
- try
+ while (!(state as TCPNetworkMonitor).Abort)
{
- while (!Abort)
+ try
{
UpdateProcessConnections();
if (_connections.Count == 0)
@@ -181,12 +192,19 @@ private void Run()
ProcessNetworkData();
- Thread.Sleep(10);
+
+ Thread.Sleep(30);
+ }
+ catch (ThreadAbortException)
+ {
+ // do nothing, thread is aborting.
+ return;
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLine("TCPNetworkMonitor Error: " + ex.ToString());
+ return;
}
- }
- catch (Exception ex)
- {
- Trace.WriteLine("TCPNetworkMonitor Error: " + ex.ToString());
}
Cleanup();
@@ -229,20 +247,20 @@ private void UpdateSockets()
bool found = false;
for (int j = 0; j < _sockets.Count; j++)
if (_connections[i].LocalIP == _sockets[j].LocalIP &&
- (!UseOneSocketPerRemoteIP || (_connections[i].RemoteIP == _sockets[j].RemoteIP)))
+ (!UseSocketFilter || (_connections[i].RemoteIP == _sockets[j].RemoteIP)))
found = true;
if (!found)
{
Trace.WriteLine("TCPNetworkMonitor: Starting " + MonitorType.ToString() + " listener on [" +
new IPAddress(_connections[i].LocalIP).ToString() + "]" +
- (UseOneSocketPerRemoteIP ? "=> [" + new IPAddress(_connections[i].RemoteIP).ToString() + "]." : ""));
+ (UseSocketFilter ? "=> [" + new IPAddress(_connections[i].RemoteIP).ToString() + "]." : ""));
if (MonitorType == NetworkMonitorType.WinPCap)
_sockets.Add(new RawPCap());
else
_sockets.Add(new RawSocket());
- _sockets.Last().Create(_connections[i].LocalIP, UseOneSocketPerRemoteIP ? _connections[i].RemoteIP : 0);
+ _sockets.Last().Create(_connections[i].LocalIP, UseSocketFilter ? _connections[i].RemoteIP : 0);
}
}
@@ -251,14 +269,14 @@ private void UpdateSockets()
bool found = false;
for (int j=0;j<_connections.Count;j++)
if (_connections[j].LocalIP == _sockets[i].LocalIP &&
- (!UseOneSocketPerRemoteIP || (_connections[j].RemoteIP == _sockets[i].RemoteIP)))
+ (!UseSocketFilter || (_connections[j].RemoteIP == _sockets[i].RemoteIP)))
found = true;
if (!found)
{
Trace.WriteLine("TCPNetworkMonitor: Stopping " + MonitorType.ToString() + " listener on [" +
new IPAddress(_sockets[i].LocalIP).ToString() + "]" +
- (UseOneSocketPerRemoteIP ? "=> [" + new IPAddress(_sockets[i].RemoteIP).ToString() + "]." : ""));
+ (UseSocketFilter ? "=> [" + new IPAddress(_sockets[i].RemoteIP).ToString() + "]." : ""));
_sockets[i].Destroy();
_sockets.RemoveAt(i);
}