* RecordProtocol.cs, SslStreamBase.cs: Ensure nothing (even the same
thread) can confuse the record decoding code. Fix bug #82145 (LDAP)
which uses several thread over a single SslClientStream instance.
svn path=/trunk/mcs/; revision=84193
+2007-08-16 Sebastien Pouliot <sebastien@ximian.com>
+
+ * RecordProtocol.cs, SslStreamBase.cs: Ensure nothing (even the same
+ thread) can confuse the record decoding code. Fix bug #82145 (LDAP)
+ which uses several thread over a single SslClientStream instance.
+
2007-05-23 Gonzalo Paniagua Javier <gonzalo.mono@gmail.com>
* Context.cs: fix the calculation of the unix time.
2007-05-23 Gonzalo Paniagua Javier <gonzalo.mono@gmail.com>
* Context.cs: fix the calculation of the unix time.
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
+ private static ManualResetEvent record_processing = new ManualResetEvent (true);
+
protected Stream innerStream;
protected Context context;
protected Stream innerStream;
protected Context context;
"The session is finished and it's no longer valid.");
}
"The session is finished and it's no longer valid.");
}
+ record_processing.Reset ();
byte[] recordTypeBuffer = new byte[1];
ReceiveRecordAsyncResult internalResult = new ReceiveRecordAsyncResult(callback, state, recordTypeBuffer, record);
byte[] recordTypeBuffer = new byte[1];
ReceiveRecordAsyncResult internalResult = new ReceiveRecordAsyncResult(callback, state, recordTypeBuffer, record);
if (internalResult.CompletedWithError)
throw internalResult.AsyncException;
if (internalResult.CompletedWithError)
throw internalResult.AsyncException;
- else
- return internalResult.ResultingBuffer;
+
+ byte[] result = internalResult.ResultingBuffer;
+ record_processing.Set ();
+ return result;
}
public byte[] ReceiveRecord(Stream record)
}
public byte[] ReceiveRecord(Stream record)
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
+ static ManualResetEvent record_processing = new ManualResetEvent (true);
+
private const int WaitTimeOut = 5 * 60 * 1000;
internal Stream innerStream;
private const int WaitTimeOut = 5 * 60 * 1000;
internal Stream innerStream;
+ record_processing.Reset ();
// do we already have some decrypted data ?
if (this.inputBuffer.Position > 0) {
// or maybe we used all the buffer before ?
// do we already have some decrypted data ?
if (this.inputBuffer.Position > 0) {
// or maybe we used all the buffer before ?
this.inputBuffer.SetLength (0);
} else {
int n = this.inputBuffer.Read (buffer, offset, count);
this.inputBuffer.SetLength (0);
} else {
int n = this.inputBuffer.Read (buffer, offset, count);
+ if (n > 0) {
+ record_processing.Set ();
needMoreData = false;
// if we loop, then it either means we need more data
byte[] recbuf = new byte[16384];
needMoreData = false;
// if we loop, then it either means we need more data
byte[] recbuf = new byte[16384];
- int n = innerStream.Read (recbuf, 0, recbuf.Length);
+ int n = 0;
+ if (count == 1) {
+ int value = innerStream.ReadByte ();
+ if (value >= 0) {
+ recbuf[0] = (byte) value;
+ n = 1;
+ }
+ } else {
+ n = innerStream.Read (recbuf, 0, recbuf.Length);
+ }
if (n > 0) {
// Add the new received data to the waiting data
if ((recordStream.Length > 0) && (recordStream.Position != recordStream.Length))
if (n > 0) {
// Add the new received data to the waiting data
if ((recordStream.Length > 0) && (recordStream.Position != recordStream.Length))
recordStream.Write (recbuf, 0, n);
} else {
// or that the read operation is done (lost connection in the case of a network stream).
recordStream.Write (recbuf, 0, n);
} else {
// or that the read operation is done (lost connection in the case of a network stream).
+ record_processing.Set ();
if (dataToReturn) {
// we have record(s) to return -or- no more available to read from network
// reset position for further reading
if (dataToReturn) {
// we have record(s) to return -or- no more available to read from network
// reset position for further reading
- return this.inputBuffer.Read (buffer, offset, count);
+ int i = inputBuffer.Read (buffer, offset, count);
+ record_processing.Set ();
+ return i;