Move some code around, improve documentation
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index e15efad..50ff986 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -1422,7 +1422,10 @@
 int ssl_handshake_step( ssl_context *ssl );
 
 /**
- * \brief          Perform an SSL renegotiation on the running connection
+ * \brief          Initiate an SSL renegotiation on the running connection.
+ *                 Client: perform the renegotiation right now.
+ *                 Server: request renegotiation, which will be performed
+ *                 during the next call to ssl_read() if honored by client.
  *
  * \param ssl      SSL context
  *
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 00372f9..94d9edf 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3998,30 +3998,23 @@
 /*
  * Actually renegotiate current connection, triggered by either:
  * - calling ssl_renegotiate() on client,
- * - receiving a HelloRequestion on client during ssl_read(),
+ * - receiving a HelloRequest on client during ssl_read(),
  * - receiving any handshake message on server during ssl_read() after the
  *   initial handshake is completed
+ * If the handshake doesn't complete due to waiting for I/O, it will continue
+ * during the next calls to ssl_renegotiate() or ssl_read() respectively.
  */
-static int ssl_do_renegotiate( ssl_context *ssl )
+static int ssl_start_renegotiation( ssl_context *ssl )
 {
     int ret;
 
     SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) );
 
-    /*
-     * If renegotiation is already in progress, skip checks/init
-     */
-    if( ssl->renegotiation != SSL_RENEGOTIATION )
-    {
-        if( ssl->state != SSL_HANDSHAKE_OVER )
-            return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+    if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
+        return( ret );
 
-        if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
-            return( ret );
-
-        ssl->state = SSL_HELLO_REQUEST;
-        ssl->renegotiation = SSL_RENEGOTIATION;
-    }
+    ssl->state = SSL_HELLO_REQUEST;
+    ssl->renegotiation = SSL_RENEGOTIATION;
 
     if( ( ret = ssl_handshake( ssl ) ) != 0 )
     {
@@ -4040,10 +4033,42 @@
  */
 int ssl_renegotiate( ssl_context *ssl )
 {
-    if( ssl->endpoint == SSL_IS_CLIENT )
-        return( ssl_do_renegotiate( ssl ) );
-    else
+    int ret;
+
+    /* On server, just send the request */
+    if( ssl->endpoint == SSL_IS_SERVER )
+    {
+        if( ssl->state != SSL_HANDSHAKE_OVER )
+            return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+
         return( ssl_write_hello_request( ssl ) );
+    }
+
+    /*
+     * On client, either start the renegotiation process or,
+     * if already in progress, continue the handshake
+     */
+    if( ssl->renegotiation != SSL_RENEGOTIATION )
+    {
+        if( ssl->state != SSL_HANDSHAKE_OVER )
+            return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+
+        if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
+        {
+            SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
+            return( ret );
+        }
+    }
+    else
+    {
+        if( ( ret = ssl_handshake( ssl ) ) != 0 )
+        {
+            SSL_DEBUG_RET( 1, "ssl_handshake", ret );
+            return( ret );
+        }
+    }
+
+    return( 0 );
 }
 
 /*
@@ -4141,9 +4166,9 @@
             }
             else
             {
-                if( ( ret = ssl_do_renegotiate( ssl ) ) != 0 )
+                if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
                 {
-                    SSL_DEBUG_RET( 1, "ssl_do_renegotiate", ret );
+                    SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
                     return( ret );
                 }
 
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 6879f3e..e4a1426 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -71,7 +71,7 @@
  * longer paquets (for fragmentation purposes) */
 #define GET_REQUEST "GET %s HTTP/1.0\r\n" /* LONG_HEADER */ "\r\n"
 
-/* Temporary, should become a runtime option later */
+/* Uncomment to test client-initiated renegotiation */
 // #define TEST_RENEGO
 
 /*
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 890c119..d35ab77 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -83,7 +83,7 @@
     "<h2>PolarSSL Test Server</h2>\r\n" \
     "<p>Successful connection using: %s</p>\r\n" // LONG_RESPONSE
 
-/* Temporary, should become a runtime option later */
+/* Uncomment to test server-initiated renegotiation */
 // #define TEST_RENEGO
 
 /*
@@ -948,15 +948,20 @@
      */
     printf( "  . Requestion renegotiation..." );
     fflush( stdout );
-    while( ( ret = ssl_write_hello_request( &ssl ) ) != 0 )
+    while( ( ret = ssl_renegotiate( &ssl ) ) != 0 )
     {
         if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
         {
-            printf( " failed\n  ! ssl_write_hello_request returned %d\n\n", ret );
+            printf( " failed\n  ! ssl_renegotiate returned %d\n\n", ret );
             goto exit;
         }
     }
 
+    /*
+     * Should be a while loop, not an if, but here we're not actually
+     * expecting data from the client, and since we're running tests locally,
+     * we can just hope the handshake will finish the during the first call.
+     */
     if( ( ret = ssl_read( &ssl, buf, 0 ) ) != 0 )
     {
         if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )