summaryrefslogtreecommitdiffstats
path: root/src/idevice.c
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2019-07-19 00:06:38 +0700
committerGravatar Nikias Bassen2019-07-19 01:11:09 +0700
commitf52584e7310ad9af414cdd22cbfad81d53417c22 (patch)
treeae4488955b67b676ca5735d622083746c339ce96 /src/idevice.c
parent2332655423c1616d8e37ece7f33e98be0e218504 (diff)
downloadlibimobiledevice-f52584e7310ad9af414cdd22cbfad81d53417c22.tar.gz
libimobiledevice-f52584e7310ad9af414cdd22cbfad81d53417c22.tar.bz2
OpenSSL: Use SSL_pending() to determine if we want a select() before SSL_read()
In order to obey the timeout in idevice_connection_receive_timeout(), we are using select() via socket_check_fd(). However, the SSL bio might have buffered more bytes than actually requested upon a call to SSL_read(), so in the next call to idevice_connection_receive_timeout() a select() would not find the fd being ready to read, and make it fail with an error, after the specified timeout is reached. With the help of SSL_pending() we can now skip calling select() so that SSL_read() will directly be called again.
Diffstat (limited to 'src/idevice.c')
-rw-r--r--src/idevice.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/src/idevice.c b/src/idevice.c
index 02d34cc..794af8b 100644
--- a/src/idevice.c
+++ b/src/idevice.c
@@ -453,19 +453,24 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_
453 453
454 if (connection->ssl_data) { 454 if (connection->ssl_data) {
455 uint32_t received = 0; 455 uint32_t received = 0;
456 int do_select = 1;
456 457
457 while (received < len) { 458 while (received < len) {
458 459#ifdef HAVE_OPENSSL
459 int conn_error = socket_check_fd((int)(long)connection->data, FDM_READ, timeout); 460 do_select = (SSL_pending(connection->ssl_data->session) == 0);
460 idevice_error_t error = socket_recv_to_idevice_error(conn_error, len, received); 461#endif
461 462 if (do_select) {
462 switch (error) { 463 int conn_error = socket_check_fd((int)(long)connection->data, FDM_READ, timeout);
463 case IDEVICE_E_SUCCESS: 464 idevice_error_t error = socket_recv_to_idevice_error(conn_error, len, received);
464 break; 465
465 case IDEVICE_E_UNKNOWN_ERROR: 466 switch (error) {
466 debug_info("ERROR: socket_check_fd returned %d (%s)", conn_error, strerror(-conn_error)); 467 case IDEVICE_E_SUCCESS:
467 default: 468 break;
468 return error; 469 case IDEVICE_E_UNKNOWN_ERROR:
470 debug_info("ERROR: socket_check_fd returned %d (%s)", conn_error, strerror(-conn_error));
471 default:
472 return error;
473 }
469 } 474 }
470 475
471#ifdef HAVE_OPENSSL 476#ifdef HAVE_OPENSSL