473,406 Members | 2,371 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

SSLStream broken due to heap fragmentation

We've been using the SSLStream class found in System.Net.Security to build a
giant Sockets server that provides TLS encryption at the channel leve.
Before .Net 2.0, we used an open-source encryption channel from Mentalis,
and have even looked at the Mono implementation for doing this.

The problem comes from the SSLStream not doing any buffer management. None.
Zero. In the "no buffer management" case, each SSLStream allocates bufferes
whenevers it needs them, copies data into those buffers, and then calls
Socket.BeingRead / Socket.BeginWrite. This causes pinning. Massive,
long-lived, horrible pins. This leads to horrendus non-recoverable
fragmentation.

The killer here is that both of these socket methods immediatly pin the
buffers, and pass the data off to unmanaged code. The BeginRead method may
not return for 10 seconds, 10 minutes, or 10 hours, leaving a hole in the
Managed Heap the entire time. BeginWrite causes the same problem, although
for a smaller length of time.

To get around this in the past, we've created a block of buffers ahead of
time, and cycled through them. This keeps all the pinned memory together in
a single spot. This technique is described in detail here:
http://blogs.msdn.com/yunjin/archive.../27/63642.aspx
http://www.coversant.net/dotnetnuke/...d=88&EntryID=9

In our last implementation (.Net 1.1), we put alot of work into managing
these buffer pools and really trying hard to eliminate heap fragmentation.
This worked great.
With the .Net 2.0 SSLStream, the BeginRead method ends up allocating
bufferes here:
BeginRead->ProcessRead->EnsureInternalBufferSize
That method allocates a buffer by:
this._InternalBuffer = new byte[addSize + curOffset];

Notice there's no fregging pool here? No attempt to eliminate fragmentation.
No attempt to be efficient.

This buffer gets passed to the NetworkStream, and in turn to the Socket,
which promptly pins it.

The BeginWrite case is the same thing:
BeginWrite->ProcessWrite->StartWriting->EncryptBuffers->EncryptData->Encrypt
This method allocates it's buffer:
buffer1 = new byte[(size + this.m_HeaderSize) + this.m_TrailerSize];

Again, no fregging attempt to use a buffer pool. No attempt to eliminate
heap fragmentation.

Because the SSLStream is retarded, it only works on NetworkStreams - and
Network Streams only work on Sockets. This means there's nowhere in the
whole chain I can insert code prior to the Pin that would use a pooled
buffer. Ugh.

Now, .Net 2.0 is improved at managing pinning in the heap:
http://blogs.msdn.com/maoni/archive/...lr-2-0-gc.aspx

.... but I have it on VERY good authority that their technique isn't nearly
as effective as the BufferPool method. In fact, it's not even close.

This has runied my whole day. Ugh.

--
Chris Mullins, MCSD.NET, MCPD:Enterprise
Nov 9 '06 #1
1 3573
We did figure out a way around this, in case anyone's interested.

By deriving a class from NetworkStream and overring the relevant methods, we
can swap out the buffers used by SSLStream with our own buffers. Because our
buffers come from a bufferpool that's allocated in a way to minimize heap
fragmentation, the heap stays unfragmented, and scalability is largely
unaffected.

We certainly end up doing number of buffer copies, but that's a much cheaper
price to pay than heap fragmentation.

--
Chris Mullins, MCSD.NET, MCPD:Enterprise
http://www.coversant.net/blogs/cmullins

"Chris Mullins" <cm******@yahoo.comwrote:
We've been using the SSLStream class found in System.Net.Security to build
a giant Sockets server that provides TLS encryption at the channel leve.
Before .Net 2.0, we used an open-source encryption channel from Mentalis,
and have even looked at the Mono implementation for doing this.

The problem comes from the SSLStream not doing any buffer management.
None. Zero. In the "no buffer management" case, each SSLStream allocates
bufferes whenevers it needs them, copies data into those buffers, and then
calls Socket.BeingRead / Socket.BeginWrite. This causes pinning. Massive,
long-lived, horrible pins. This leads to horrendus non-recoverable
fragmentation.

The killer here is that both of these socket methods immediatly pin the
buffers, and pass the data off to unmanaged code. The BeginRead method may
not return for 10 seconds, 10 minutes, or 10 hours, leaving a hole in the
Managed Heap the entire time. BeginWrite causes the same problem, although
for a smaller length of time.

To get around this in the past, we've created a block of buffers ahead of
time, and cycled through them. This keeps all the pinned memory together
in a single spot. This technique is described in detail here:
http://blogs.msdn.com/yunjin/archive.../27/63642.aspx
http://www.coversant.net/dotnetnuke/...d=88&EntryID=9

In our last implementation (.Net 1.1), we put alot of work into managing
these buffer pools and really trying hard to eliminate heap fragmentation.
This worked great.
With the .Net 2.0 SSLStream, the BeginRead method ends up allocating
bufferes here:
BeginRead->ProcessRead->EnsureInternalBufferSize
That method allocates a buffer by:
this._InternalBuffer = new byte[addSize + curOffset];

Notice there's no fregging pool here? No attempt to eliminate
fragmentation. No attempt to be efficient.

This buffer gets passed to the NetworkStream, and in turn to the Socket,
which promptly pins it.

The BeginWrite case is the same thing:
BeginWrite->ProcessWrite->StartWriting->EncryptBuffers->EncryptData->Encrypt
This method allocates it's buffer:
buffer1 = new byte[(size + this.m_HeaderSize) + this.m_TrailerSize];

Again, no fregging attempt to use a buffer pool. No attempt to eliminate
heap fragmentation.

Because the SSLStream is retarded, it only works on NetworkStreams - and
Network Streams only work on Sockets. This means there's nowhere in the
whole chain I can insert code prior to the Pin that would use a pooled
buffer. Ugh.

Now, .Net 2.0 is improved at managing pinning in the heap:
http://blogs.msdn.com/maoni/archive/...lr-2-0-gc.aspx

... but I have it on VERY good authority that their technique isn't nearly
as effective as the BufferPool method. In fact, it's not even close.

This has runied my whole day. Ugh.

--
Chris Mullins, MCSD.NET, MCPD:Enterprise

Nov 10 '06 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
by: Tron Thomas | last post by:
Given the following information about memory management in C++: ----- The c-runtime dynamic memory manager (and most other commercial memory managers) has issues with fragmentation similar to a...
22
by: MSG | last post by:
Hello void f1(int n) { vector<int> x(n); /* C++ */ } void f2(int n) { int x; /* C99 only */ } void f3(int n) { int* x = new int; /* C++ */ delete x; }
1
by: kmounkhaty | last post by:
Hi guru, I've been new company for only a month and started analysing Index Fragmentation. After I ran DBCC DBREINDEX and capture data into permanent table, I 've seen lots of tables with no...
0
by: Jakob Nielsen | last post by:
This is a question about partly .net sslStreams and partly about the certificates it uses. I can't seem to find a more specific group.. and since i am coding in c# :-) I try creating a sslStream...
9
by: swengtoo | last post by:
My understanding is that an auto_ptr can never own an object that was created on the stack. This is because when auto_ptr goes out of scope, it calls 'delete' for the object it points to. Is my...
3
by: Ben Lam | last post by:
I read on some message board that i can't find anymore saying that the Large Object Heap is compacted in Framework 1.1 or 2.0. Is this true? I can't seem to find any ms documentation that said...
0
by: phplasma | last post by:
Hey, I am currently attempting to implement a multi-threaded C# socket, using SSL (.pem file/certification/private key combo) server using Visual Studio C# Express. I have successfully made...
5
by: Andreas Schmitt | last post by:
Hi, I recently worked on an open source project and tried to make on of the arrays they are using dynamically allocated to get rid of the max size. I used the realloc instead of the usual C++...
1
by: nevviin | last post by:
Hi, I have developed a VB.NET windows application to read mails from the server. I am using tcpclient object to read mail from mail server. I am uisng the IMAP and POP protocols for reading...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.