diff options
| author | 2019-06-13 02:01:04 +0300 | |
|---|---|---|
| committer | 2019-06-13 01:41:20 +0200 | |
| commit | 4d8b89223cbc9f530cc650ab5131c09eab1af258 (patch) | |
| tree | e63216393208c07ae83c7b8eba5e0a9546de4fef /src/idevice.c | |
| parent | 6edc36fccb52a963c9ebfbb44ba7b91570e0fd06 (diff) | |
| download | libimobiledevice-4d8b89223cbc9f530cc650ab5131c09eab1af258.tar.gz libimobiledevice-4d8b89223cbc9f530cc650ab5131c09eab1af258.tar.bz2 | |
Timeout support for SSL connections and better timeout handeling.
Diffstat (limited to 'src/idevice.c')
| -rw-r--r-- | src/idevice.c | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/src/idevice.c b/src/idevice.c index be29884..5d5c950 100644 --- a/src/idevice.c +++ b/src/idevice.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | 43 | ||
| 44 | #include "idevice.h" | 44 | #include "idevice.h" |
| 45 | #include "common/userpref.h" | 45 | #include "common/userpref.h" |
| 46 | #include "common/socket.h" | ||
| 46 | #include "common/thread.h" | 47 | #include "common/thread.h" |
| 47 | #include "common/debug.h" | 48 | #include "common/debug.h" |
| 48 | 49 | ||
| @@ -381,6 +382,24 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_send(idevice_connection_ | |||
| 381 | return internal_connection_send(connection, data, len, sent_bytes); | 382 | return internal_connection_send(connection, data, len, sent_bytes); |
| 382 | } | 383 | } |
| 383 | 384 | ||
| 385 | static idevice_error_t socket_recv_to_idevice_error(int conn_error, uint32_t len, uint32_t received) | ||
| 386 | { | ||
| 387 | if (conn_error < 0) { | ||
| 388 | switch (conn_error) { | ||
| 389 | case -EAGAIN: | ||
| 390 | debug_info("ERROR: received partial data %d/%d (%s)", received, len, strerror(-conn_error)); | ||
| 391 | return IDEVICE_E_NOT_ENOUGH_DATA; | ||
| 392 | case -ETIMEDOUT: | ||
| 393 | debug_info("ERROR: received timeout (%s)", strerror(-conn_error)); | ||
| 394 | return IDEVICE_E_TIMEOUT; | ||
| 395 | default: | ||
| 396 | return IDEVICE_E_UNKNOWN_ERROR; | ||
| 397 | } | ||
| 398 | } | ||
| 399 | |||
| 400 | return IDEVICE_E_SUCCESS; | ||
| 401 | } | ||
| 402 | |||
| 384 | /** | 403 | /** |
| 385 | * Internally used function for receiving raw data over the given connection | 404 | * Internally used function for receiving raw data over the given connection |
| 386 | * using a timeout. | 405 | * using a timeout. |
| @@ -392,12 +411,14 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t | |||
| 392 | } | 411 | } |
| 393 | 412 | ||
| 394 | if (connection->type == CONNECTION_USBMUXD) { | 413 | if (connection->type == CONNECTION_USBMUXD) { |
| 395 | int res = usbmuxd_recv_timeout((int)(long)connection->data, data, len, recv_bytes, timeout); | 414 | int conn_error = usbmuxd_recv_timeout((int)(long)connection->data, data, len, recv_bytes, timeout); |
| 396 | if (res < 0) { | 415 | idevice_error_t error = socket_recv_to_idevice_error(conn_error, len, *recv_bytes); |
| 397 | debug_info("ERROR: usbmuxd_recv_timeout returned %d (%s)", res, strerror(errno)); | 416 | |
| 398 | return (res == -EAGAIN ? IDEVICE_E_NOT_ENOUGH_DATA : IDEVICE_E_UNKNOWN_ERROR); | 417 | if (error == IDEVICE_E_UNKNOWN_ERROR) { |
| 418 | debug_info("ERROR: usbmuxd_recv_timeout returned %d (%s)", conn_error, strerror(-conn_error)); | ||
| 399 | } | 419 | } |
| 400 | return IDEVICE_E_SUCCESS; | 420 | |
| 421 | return error; | ||
| 401 | } else { | 422 | } else { |
| 402 | debug_info("Unknown connection type %d", connection->type); | 423 | debug_info("Unknown connection type %d", connection->type); |
| 403 | } | 424 | } |
| @@ -406,13 +427,27 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t | |||
| 406 | 427 | ||
| 407 | LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) | 428 | LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) |
| 408 | { | 429 | { |
| 409 | if (!connection || (connection->ssl_data && !connection->ssl_data->session)) { | 430 | if (!connection || (connection->ssl_data && !connection->ssl_data->session) || len == 0) { |
| 410 | return IDEVICE_E_INVALID_ARG; | 431 | return IDEVICE_E_INVALID_ARG; |
| 411 | } | 432 | } |
| 412 | 433 | ||
| 413 | if (connection->ssl_data) { | 434 | if (connection->ssl_data) { |
| 414 | uint32_t received = 0; | 435 | uint32_t received = 0; |
| 436 | |||
| 415 | while (received < len) { | 437 | while (received < len) { |
| 438 | |||
| 439 | int conn_error = socket_check_fd((int)(long)connection->data, FDM_READ, timeout); | ||
| 440 | idevice_error_t error = socket_recv_to_idevice_error(conn_error, len, received); | ||
| 441 | |||
| 442 | switch (error) { | ||
| 443 | case IDEVICE_E_SUCCESS: | ||
| 444 | break; | ||
| 445 | case IDEVICE_E_UNKNOWN_ERROR: | ||
| 446 | debug_info("ERROR: socket_check_fd returned %d (%s)", conn_error, strerror(-conn_error)); | ||
| 447 | default: | ||
| 448 | return error; | ||
| 449 | } | ||
| 450 | |||
| 416 | #ifdef HAVE_OPENSSL | 451 | #ifdef HAVE_OPENSSL |
| 417 | int r = SSL_read(connection->ssl_data->session, (void*)((char*)(data+received)), (int)len-received); | 452 | int r = SSL_read(connection->ssl_data->session, (void*)((char*)(data+received)), (int)len-received); |
| 418 | #else | 453 | #else |
| @@ -424,13 +459,15 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_ | |||
| 424 | break; | 459 | break; |
| 425 | } | 460 | } |
| 426 | } | 461 | } |
| 462 | |||
| 427 | debug_info("SSL_read %d, received %d", len, received); | 463 | debug_info("SSL_read %d, received %d", len, received); |
| 428 | if (received > 0) { | 464 | if (received < len) { |
| 429 | *recv_bytes = received; | 465 | *recv_bytes = 0; |
| 430 | return IDEVICE_E_SUCCESS; | 466 | return IDEVICE_E_SSL_ERROR; |
| 431 | } | 467 | } |
| 432 | *recv_bytes = 0; | 468 | |
| 433 | return IDEVICE_E_SSL_ERROR; | 469 | *recv_bytes = received; |
| 470 | return IDEVICE_E_SUCCESS; | ||
| 434 | } | 471 | } |
| 435 | return internal_connection_receive_timeout(connection, data, len, recv_bytes, timeout); | 472 | return internal_connection_receive_timeout(connection, data, len, recv_bytes, timeout); |
| 436 | } | 473 | } |
