6

When using an SSLStream to send a 'large' chunk of data (1 meg) to a (already authenticated) client, the packet fragmentation / dissasembly I'm seeing is FAR greater than when using a normal NetworkStream.

Using an async read on the client (i.e. BeginRead()), the ReadCallback is repeatedly called with exactly the same size chunk of data up until the final packet (the remainder of the data). With the data I'm sending (it's a zip file), the segments happen to be 16363 bytes long. Note: My receive buffer is much bigger than this and changing it's size has no effect

I understand that SSL encrypts data in chunks no bigger than 18Kb, but since SSL sits on top of TCP, I wouldn't think that the number of SSL chunks would have any relevance to the TCP packet fragmentation?

Essentially, the data is taking about 20 times longer to be fully read by the client than with a standard NetworkStream (both on localhost!)

What am I missing?


EDIT:

I'm beginning to suspect that the receive (or send) buffer size of an SSLStream is limited. Even if I use synchronous reads (i.e. SSLStream.Read()), no more data ever becomes available, regardless of how long I wait before attempting to read. This would be the same behavior as if I were to limit the receive buffer to 16363 bytes. Setting the Underlying NetworkStream's SendBufferSize (on the server), and ReceiveBufferSize (on the client) has no effect.

Ive
  • 457
  • 5
  • 19
  • Are you talking about IP fragmentation or about how many reads you have to make on the receiver side? – Nikolai Fetissov Jun 22 '12 at 16:00
  • The number of reads that are made – Ive Jun 22 '12 at 16:11
  • How are you sending? If you don't use buffers around SSL streams you can get a data explosion of over 40x due to encoding one byte at a time in its own SSL record. – user207421 Jun 22 '12 at 23:45
  • @EJP: Can you elaborate please? With the individual packet sizes of 16K, I don't think this sounds like single bytes of encrypted data. Are you referring to using a BufferedStream or some such? Wrapping the underling NetworkStream in a BufferedStream has no effect (and I believe this would just help with heap fragmentation anyway). The consistency of the read-packet size points to the SSLStream having a fixed/limited-size receive buffer. Could this be the case? Perhaps the receive-buffer size of the underling NetworkStream is ignored for SSL for packets over a certain size? – Ive Jun 26 '12 at 09:01
  • fragmentation and chunk size depends on all devices on the network path between the sender and the receiver. There is no way to influence this – Mario The Spoon Jun 26 '12 at 09:19
  • @Mario: If the if the plain (non SSL) stream behaved in the same way or even if packet sizes were irregular, then I'd agree; however I think the consistent nature of the packet fragmentation could point to something else? – Ive Jun 26 '12 at 10:02
  • Besides what Ive describes, something similar seems to have started at a much lower threshold in Windows 10 and Server 2016. I have an old application (framework 2.0) that sends 162 byte long packets through an SslStream at a relatively low frequency (one packet every 15 seconds). From Windows 2000 through 2012 R2, those packets always just caused a single read event (callback just called once). In Windows 10 and Server 2016, the first byte of data arrives by itself, and the remaining 161 bytes in a second read. Writes at the sending side are a single call passing all 162. – Luc VdV Feb 27 '18 at 08:32
  • PS at my previous comment: the difference is made at the sending side, what OS version the receiver is running on does not make a difference. The OS used at the sending side determines whether the receiver will get it in 1 or 2 reads. – Luc VdV Feb 27 '18 at 08:37
  • @LucVdV, although unrelated to this question, I came across this behavior too recently. I'll try to find the reference, but this behavior (only a single byte sent in the first package for SSL writes) was introduced on purpose to address a security vulnerability. Essentially this behavior is by design; just ensure that your receiving code correctly buffers data and checks for a complete packet, regardless of how many fragments it happens to be split into. – Ive Mar 12 '18 at 10:07

1 Answers1

1

This looks like a packet-data-size limitation applied by the SslStream defined by a private member:

SSLStream._SslState.MaxDataSize

I'm struggling to understand why this limitation is applied, or if it can be changed, and have asked the question here

Community
  • 1
  • 1
Ive
  • 457
  • 5
  • 19