diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 8ab7baa26..be9d07b28 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1748,16 +1748,111 @@ data_exchange: printf( " < Read from client:" ); fflush( stdout ); - do + /* + * TLS and DTLS need different reading styles (stream vs datagram) + */ + if( opt.transport == SSL_TRANSPORT_STREAM ) + { + do + { + int terminated = 0; + len = sizeof( buf ) - 1; + memset( buf, 0, sizeof( buf ) ); + ret = ssl_read( &ssl, buf, len ); + + if( ret == POLARSSL_ERR_NET_WANT_READ || + ret == POLARSSL_ERR_NET_WANT_WRITE ) + continue; + + if( ret <= 0 ) + { + switch( ret ) + { + case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY: + printf( " connection was closed gracefully\n" ); + goto close_notify; + + case 0: + case POLARSSL_ERR_NET_CONN_RESET: + printf( " connection was reset by peer\n" ); + ret = POLARSSL_ERR_NET_CONN_RESET; + goto reset; + + default: + printf( " ssl_read returned -0x%x\n", -ret ); + goto reset; + } + } + + if( ssl_get_bytes_avail( &ssl ) == 0 ) + { + len = ret; + buf[len] = '\0'; + printf( " %d bytes read\n\n%s\n", len, (char *) buf ); + + /* End of message should be detected according to the syntax of the + * application protocol (eg HTTP), just use a dummy test here. */ + if( buf[len - 1] == '\n' ) + terminated = 1; + } + else + { + int extra_len, ori_len; + unsigned char *larger_buf; + + ori_len = ret; + extra_len = ssl_get_bytes_avail( &ssl ); + + larger_buf = polarssl_malloc( ori_len + extra_len + 1 ); + if( larger_buf == NULL ) + { + printf( " ! memory allocation failed\n" ); + ret = 1; + goto reset; + } + + memset( larger_buf, 0, ori_len + extra_len ); + memcpy( larger_buf, buf, ori_len ); + + /* This read should never fail and get the whole cached data */ + ret = ssl_read( &ssl, larger_buf + ori_len, extra_len ); + if( ret != extra_len || + ssl_get_bytes_avail( &ssl ) != 0 ) + { + printf( " ! ssl_read failed on cached data\n" ); + ret = 1; + goto reset; + } + + larger_buf[ori_len + extra_len] = '\0'; + printf( " %u bytes read (%u + %u)\n\n%s\n", + ori_len + extra_len, ori_len, extra_len, + (char *) larger_buf ); + + /* End of message should be detected according to the syntax of the + * application protocol (eg HTTP), just use a dummy test here. */ + if( larger_buf[ori_len + extra_len - 1] == '\n' ) + terminated = 1; + + polarssl_free( larger_buf ); + } + + if( terminated ) + { + ret = 0; + break; + } + } + while( 1 ); + } + else /* Not stream, so datagram */ { - int terminated = 0; len = sizeof( buf ) - 1; memset( buf, 0, sizeof( buf ) ); - ret = ssl_read( &ssl, buf, len ); - if( ret == POLARSSL_ERR_NET_WANT_READ || - ret == POLARSSL_ERR_NET_WANT_WRITE ) - continue; + do ret = ssl_read( &ssl, buf, len ); + while( ret == POLARSSL_ERR_NET_WANT_READ || + ret == POLARSSL_ERR_NET_WANT_WRITE ); if( ret <= 0 ) { @@ -1765,13 +1860,14 @@ data_exchange: { case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY: printf( " connection was closed gracefully\n" ); + ret = 0; goto close_notify; case 0: case POLARSSL_ERR_NET_CONN_RESET: printf( " connection was reset by peer\n" ); - ret = POLARSSL_ERR_NET_CONN_RESET; - goto reset; + ret = POLARSSL_ERR_NET_CONN_RESET; + goto reset; default: printf( " ssl_read returned -0x%x\n", -ret ); @@ -1779,66 +1875,11 @@ data_exchange: } } - if( ssl_get_bytes_avail( &ssl ) == 0 ) - { - len = ret; - buf[len] = '\0'; - printf( " %d bytes read\n\n%s\n", len, (char *) buf ); - - /* End of message should be detected according to the syntax of the - * application protocol (eg HTTP), just use a dummy test here. */ - if( buf[len - 1] == '\n' ) - terminated = 1; - } - else - { - int extra_len, ori_len; - unsigned char *larger_buf; - - ori_len = ret; - extra_len = ssl_get_bytes_avail( &ssl ); - - larger_buf = polarssl_malloc( ori_len + extra_len + 1 ); - if( larger_buf == NULL ) - { - printf( " ! memory allocation failed\n" ); - ret = 1; - goto reset; - } - - memset( larger_buf, 0, ori_len + extra_len ); - memcpy( larger_buf, buf, ori_len ); - - /* This read should never fail and get the whole cached data */ - ret = ssl_read( &ssl, larger_buf + ori_len, extra_len ); - if( ret != extra_len || - ssl_get_bytes_avail( &ssl ) != 0 ) - { - printf( " ! ssl_read failed on cached data\n" ); - ret = 1; - goto reset; - } - - larger_buf[ori_len + extra_len] = '\0'; - printf( " %u bytes read (%u + %u)\n\n%s\n", - ori_len + extra_len, ori_len, extra_len, - (char *) larger_buf ); - - /* End of message should be detected according to the syntax of the - * application protocol (eg HTTP), just use a dummy test here. */ - if( larger_buf[ori_len + extra_len - 1] == '\n' ) - terminated = 1; - - polarssl_free( larger_buf ); - } - - if( terminated ) - { - ret = 0; - break; - } + len = ret; + buf[len] = '\0'; + printf( " %d bytes read\n\n%s", len, (char *) buf ); + ret = 0; } - while( 1 ); /* * 7a. Request renegotiation while client is waiting for input from us.