Skip to content

Commit

Permalink
Merge pull request NETMF#342 from Eclo/Fix-Emulator-hanging-when-usin…
Browse files Browse the repository at this point in the history
…g-TLS/SSL--

Fix emulator hanging when using TLS/SSL
  • Loading branch information
smaillet-ms committed Nov 12, 2015
2 parents 259de22 + e378787 commit e50a067
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 19 deletions.
35 changes: 34 additions & 1 deletion Framework/Tools/Emulator/Sockets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,39 @@ internal void ClearSocketEvent(int socket, bool fRead)
}
}

internal void SignalSocketEvent(int socket, bool fRead)
{
SocketData sd;
if (_isInitialized)
{
if (GetSocketData(socket, out sd))
{
if (fRead)
{
lock (m_read)
{
if (!m_read.Contains(sd.Socket))
{
m_read.Add(sd.Socket);
}
}
}
else
{
lock (m_write)
{
if (!m_write.Contains(sd.Socket))
{
m_write.Add(sd.Socket);
}
}
}
}

SignalThread();
}
}

bool _socketsShuttingDown = false;

List<Socket> m_read = new List<Socket>();
Expand Down Expand Up @@ -430,7 +463,7 @@ void WaitForNetworkEvents()
this.Emulator.SetSystemEvents(Events.SystemEvents.SOCKET);
}
}

[MethodImplAttribute(MethodImplOptions.Synchronized)]
void EnsureInitialized()
{
Expand Down
93 changes: 75 additions & 18 deletions Framework/Tools/Emulator/Ssl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,13 @@ internal SslReadData(int socket, byte[] data)
internal byte[] ManagedBuffer;
internal int Socket;
internal int Length;
internal int Offset;
}

internal SslStream m_stream;
internal SslAsyncState m_state = SslAsyncState.Init;
internal object m_asyncData = null;
internal SslReadData m_readData;
}

Dictionary<int, SslData> _sslDataCollection = new Dictionary<int, SslData>();
Expand Down Expand Up @@ -430,38 +432,78 @@ public int Write( int socket, IntPtr Data, int size )
}


[MethodImplAttribute(MethodImplOptions.Synchronized)]
public int Read(int socket, IntPtr Data, int size)
{
int len = 0;
SslStreamData ssd;

if (!GetSslData(socket, out ssd)) return (int)SocketError.SocketError;

try
{
byte[] managedBuffer = new byte[size];

len = ssd.m_stream.Read(managedBuffer, 0, size);
if (ssd.m_state == SslStreamData.SslAsyncState.Failed)
return _socketsDriver.ReturnError(SocketError.ConnectionReset);

if (len > 0)
{
Marshal.Copy(managedBuffer, 0, Data, len);
}
else
var readData = ssd.m_readData;
if (readData != null)
{
lock (ssd)
{
_socketsDriver.ClearSocketEvent(socket, true);
len = Math.Min(size, readData.Length - readData.Offset);
if (len > 0)
{
Marshal.Copy(readData.ManagedBuffer, readData.Offset, Data, len);
readData.Offset += len;
if (readData.Offset == readData.Length) ssd.m_readData = null;
}
else
{
_socketsDriver.ClearSocketEvent(socket, true);
len = -2;
}
}
}
catch (Exception e)
else
{
Console.Error.WriteLine("Write Failed... " + e.Message);
return (int)SocketError.SocketError;
try
{
byte[] managedBuffer = new byte[size];

ssd.m_readData = new SslStreamData.SslReadData(socket, managedBuffer);
ssd.m_stream.BeginRead(managedBuffer, 0, size, this.EndRead, ssd.m_readData);
len = -2;
}
catch (Exception e)
{
Console.Error.WriteLine("Write Failed... " + e.Message);
len = (int)SocketError.SocketError;
}
}

return len;
}

void EndRead(IAsyncResult result)
{
var readData = (SslStreamData.SslReadData)result.AsyncState;
SslStreamData ssd;
if (!GetSslData(readData.Socket, out ssd)) return;

lock (ssd)
{
try
{
readData.Length = ssd.m_stream.EndRead(result);
}
catch (Exception e)
{
Console.Error.WriteLine("Read Failed... " + e.Message);
ssd.m_readData = null;
ssd.m_state = SslStreamData.SslAsyncState.Failed;
}

_socketsDriver.SignalSocketEvent(readData.Socket, true);
}
}

public int CloseSocket( int socket )
{
lock (_sslStreams)
Expand Down Expand Up @@ -606,11 +648,26 @@ public int DataAvailable( int socket )
SslStreamData ssd;
Socket sock = null;

if (!GetSslData(socket, out ssd)) return (int)SocketError.SocketError;
if (!GetSslData(socket, out ssd))
{
return (int)SocketError.SocketError;
}

if(!_socketsDriver.GetSocket(socket, out sock)) return (int)SocketError.SocketError;
if (!_socketsDriver.GetSocket(socket, out sock))
{
return (int)SocketError.SocketError;
}

return sock.Poll(0,SelectMode.SelectRead) ? 1024 : 0;
var readData = ssd.m_readData;

if(readData != null)
{
return (readData.Length - readData.Offset);
}
else
{
return sock.Poll(0, SelectMode.SelectRead) ? 1024 : 0;
}
}
}
}

0 comments on commit e50a067

Please sign in to comment.