Skip to content

Commit

Permalink
Minor thread end changes, misc minor changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ravahn committed Mar 21, 2018
1 parent 909570b commit 3b2f0ae
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 50 deletions.
4 changes: 2 additions & 2 deletions Machina.FFXIV/FFXIVNetworkMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public Boolean UseSocketFilter
public delegate void MessageReceivedDelegate(string connection, long epoch, byte[] message);

/// <summary>
/// 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.
/// </summary>
public MessageReceivedDelegate MessageReceived = null;

Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion Machina.Tests/TCPNetworkMonitorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions Machina/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]

66 changes: 46 additions & 20 deletions Machina/RawPCap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,14 @@ public void Destroy()
else
break;

_thread.Abort();
try
{
if (_thread.IsAlive)
_thread.Abort();
}
catch (Exception)
{
}
_thread = null;
}

Expand Down Expand Up @@ -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)
Expand All @@ -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;
}

Expand All @@ -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;

Expand All @@ -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
{

Expand All @@ -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);
}
}

}
Expand All @@ -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;
// }
// }
Expand Down
2 changes: 1 addition & 1 deletion Machina/RawSocket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
}
Expand Down
66 changes: 42 additions & 24 deletions Machina/TCPNetworkMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}

/// <summary>
Expand All @@ -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()
Expand All @@ -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)
Expand All @@ -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();
Expand Down Expand Up @@ -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);
}
}

Expand All @@ -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);
}
Expand Down

0 comments on commit 3b2f0ae

Please sign in to comment.