Hello all,

I'm struggling with an issue which occurs when we use OpenSSL on a normal socket (TSslWSocketClient connecting to TSslWSocketServer).

If put very short, the problem means that at some point, data sent from the client to the server is never received by the server. If this state occurs, any data sent from client to server simply is not received anymore for that connection, data sent from the server to the client still is received by the client. No error or other events on the client when we are in this state, the connection still seems to be up.

I've been working to make the problem as small as possible, and I end up with a little application which reproduces this issue 100% of the time. If we try the same application, just without using SSL (TWSocketClient connecting to TCustomMultiListenWSocketServer) the problem cannot be reproduced, hence the problem seems to lie around OpenSSL. This application is made using Delphi XE7 with the latest stable ICS version (8.18), using the latest stable OpenSSL version (1.0.2d).

The application runs both the client and the server, and functions as follows.

1) When the client gets an OnSslHandshakeDone event, it will do a PostMessage(WM_USER) to itself. 2) When this WM_USER is handled, the client will sent a random number to the server, where (8192 <= number < 9215) 3) When the server receives this number, it will generate a block of data of the length of that number, fill it with some random ansi data, and send it back to the client (with a term character at the end). 3) The client will receive the data and buffer it, when it receives the term character it throws away all data and do a PostMessage(WM_USER) to itself, back to step 2

This game of answer and reply works ok, and looks like this in log:

16:13:01.122 client    application    connected (0)
16:13:01.268    server    application    client connected (0)
16:13:01.357    server    application    SSL handshake done (0)
16:13:01.359    client    application    SSL handshake done (0)
16:13:01.359    client    application    sending request (8967)
16:13:01.359    server    application    rx request for 8967 bytes
16:13:01.360    client    application    rx 4096 bytes of data
16:13:01.361    client    application    rx 4096 bytes of data
16:13:01.361    client    application    rx 776 bytes of data
16:13:01.361    client    application    rx complete block (8967 bytes)
16:13:01.361    client    application    sending request (9190)
16:13:01.361    server    application    rx request for 9190 bytes
16:13:01.362    client    application    rx 4096 bytes of data
16:13:01.362    client    application    rx 4096 bytes of data
16:13:01.363    client    application    rx 999 bytes of data
16:13:01.363    client    application    rx complete block (9190 bytes)
...etc


The problem is triggered, when we do two times PostMessage(WM_USER) in the OnSslHandshakeDone event, expected behavior would be that the client sends a random number twice, server receives the first, sends x bytes and term char, client receives it, sends next random number (3th), server might be handling the 2nd number, etc.
However, what happens is this:
- client sends random number (#1) and another random number (#2)
- server receives random number (#1) and sends x bytes + term char back to client - client receives x bytes from random number #1 + term char from server and sends a new random number (#3) - server receives random number (#2) and sends x bytes + term char back to client - client receives x bytes from random number #2 + term char from server and sends a new random number (#4)

And there it stops, random number #3 and #4 are never received by the server, this behavior is found here exactly the same every time run.

The application produces log like above, but also all log which is gathered by ICS logger using [loSslErr, loSslInfo, loSslDump] for both client and server. If you dig into that log it always ends with the last random number sent by the client being picked up by SSL, it looks like it's being sent (Do_FD_WRITE), some SSL stuff, everything looks normal, it's just never received by the server. Snippet of long when it goes wrong:

16:32:02.516 client    application    sending request (8272)
16:32:02.516 client loSslInfo 02424090 PutDataInSslBuffer 512 len 4 [609]
16:32:02.516    client    loSslInfo 02424090 SslTryToSend 512
16:32:02.516 client loSslInfo 02424090 BIO_write(sslbio, 0x2442B80, 4) = 4 [610] 16:32:02.516 client loSslInfo 02424090 BIO_ctrl(sslbio, BIO_CTRL_FLUSH, 0, 0x0) = 1 [611] 16:32:02.516 client loSslInfo 02424090 TriggerEvents 512 SslState: SSL_ST_OK // MayFD_Read=0 MayDoRecv=-1 MayFD_Write=-1 MaySslTryToSend=-1 bSslAllSent=-1 bAllSent=0 16:32:02.516 client loSslInfo 02424090 BIO_ctrl_pending(nbio) = 33 [612]
16:32:02.516    client    loSslInfo 02424090 TriggerEvent sslFdWrite 512
16:32:02.516 client loSslInfo 02424090 BIO_ctrl_pending(sslbio) = 0 [613] 16:32:02.516 client loSslInfo 02424090 BIO_ctrl_get_write_guarantee(nbio) = 4096 [614]
16:32:02.516    client    loSslInfo 02424090 SslAsyncSelect 512, 2 FD_WRITE
16:32:02.516 client loSslInfo 02424090 TCustomSslWSocket.Do_FD_WRITE 512 16:32:02.516 client loSslInfo 02424090 BIO_ctrl_pending(nbio) = 33 [615] 16:32:02.516 client loSslInfo 02424090 BIO_read(nbio, 0x18BCE4, 33) = 33 [616] 16:32:02.517 client loSslInfo 02424090 my_RealSend (0x200, 1621220, 33) = 33 [617] 16:32:02.517 client loSslInfo 02424090 BIO_ctrl_pending(nbio) = 0 [618] 16:32:02.517 client loSslInfo 02424090 BIO_ctrl_pending(nbio) = 0 [619] 16:32:02.517 client loSslInfo 02424090 TriggerEvents 512 SslState: SSL_ST_OK // MayFD_Read=0 MayDoRecv=-1 MayFD_Write=-1 MaySslTryToSend=-1 bSslAllSent=-1 bAllSent=-1 16:32:02.517 client loSslInfo 02424090 BIO_ctrl_pending(nbio) = 0 [620] 16:32:02.517 client loSslInfo 02424090 BIO_ctrl_pending(sslbio) = 0 [621] 16:32:02.517 client loSslInfo 02424090 BIO_ctrl_get_write_guarantee(nbio) = 4096 [622]
... deafening silence


The source of the application, plus all required stuff from ICS, plus the OpenSSL libraries and certificates can be downloaded here: http://www.xs4all.nl/~bosma/SSL_Server_Client_test_source.zip A compiled version, plus the OpenSSL libraries and certificates can be downloaded here: http://www.xs4all.nl/~bosma/SSL_Server_Client_test_binary.zip

The application can also be compiled without USE_SSL, then it'll work fine.

Sorry for the long post, I tried to keep it as brief as possible, I hope someone can help or point me into the right direction :)

thanks in advance!

Merijn






--
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to