diff --git a/README.md b/README.md index 0b0b79d..0b22019 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,37 @@ buggy_openssl_with_fullduplex ============================= Toy code which shows problems with non-blocking, fullduplex I/O & renegotiation in OpenSSL + + +How it works: + + Client & Server: + - it has two threads - sender & receiver + - writes and reads are mutexed + + Client: + - I/O is blocking (but can be non-blocking) + + Server: + - I/O is non-blocking + - each thread runs it's own select() + + 1. After client & server are connected (and SSL handshake done) client sender + thread starts sending first message (in a loop). + + 2. When server receives first query it starts sending string EXCHANGE_STRING for + SEND_ITERATIONS number of times. So now we have 4 threads that are sending + and receiving traffic at the same time ( 2 send/receive threads on each + server and client side ) + + 3. When client receives RENEG_INIT_LEN number of characters it starts + renegotiation ( if other one is not pending ). Bug starts to occure here + + BUG: + Client side: client starts to report SSL_ERROR_SYSCALL + Server side: server reports SSL_ERROR_WANT_READ when receive function is called + + TCP: + In TCP exchange we can see that transfer between client & server is OK until + client sends "Client Hello" packet. This packet is sent when SSL_renegotiate + is called \ No newline at end of file diff --git a/client.cpp b/client.cpp index 7a19cba..0f7bbce 100644 --- a/client.cpp +++ b/client.cpp @@ -45,9 +45,11 @@ bool handle_error_code(int& len, SSL* SSLHandler, int code, const char* func) break; case SSL_ERROR_WANT_READ: cout << func << " WANT READ" << endl; + return true; break; case SSL_ERROR_WANT_WRITE: cout << func << " WANT WRITE" << endl; + return true; break; case SSL_ERROR_SYSCALL: cout << func << " ESYSCALL" << endl; @@ -55,10 +57,12 @@ bool handle_error_code(int& len, SSL* SSLHandler, int code, const char* func) break; case SSL_ERROR_SSL: cout << func << " ESSL" << endl; + return true; exit(1); break; default: cout << func << " SOMETHING ELSE" << endl; + return true; exit(1); } @@ -75,9 +79,7 @@ void Sender() int len = 0; do { - bool flag = true; - - while( flag ) + while( 1 ) { lock_guard lock(WriteReadMutex); cout << "SSL_write: start" << endl;