From 4d8b89223cbc9f530cc650ab5131c09eab1af258 Mon Sep 17 00:00:00 2001 From: DanyL Date: Thu, 13 Jun 2019 02:01:04 +0300 Subject: Timeout support for SSL connections and better timeout handeling. --- src/property_list_service.c | 116 +++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 56 deletions(-) (limited to 'src/property_list_service.c') diff --git a/src/property_list_service.c b/src/property_list_service.c index f411699..a6e3e24 100644 --- a/src/property_list_service.c +++ b/src/property_list_service.c @@ -48,6 +48,10 @@ static property_list_service_error_t service_to_property_list_service_error(serv return PROPERTY_LIST_SERVICE_E_MUX_ERROR; case SERVICE_E_SSL_ERROR: return PROPERTY_LIST_SERVICE_E_SSL_ERROR; + case SERIVCE_E_NOT_ENOUGH_DATA: + return PROPERTY_LIST_SERVICE_E_NOT_ENOUGH_DATA; + case SERVICE_E_TIMEOUT: + return PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT; default: break; } @@ -108,7 +112,7 @@ static property_list_service_error_t internal_plist_send(property_list_service_c char *content = NULL; uint32_t length = 0; uint32_t nlen = 0; - int bytes = 0; + uint32_t bytes = 0; if (!client || (client && !client->parent) || !plist) { return PROPERTY_LIST_SERVICE_E_INVALID_ARG; @@ -126,13 +130,13 @@ static property_list_service_error_t internal_plist_send(property_list_service_c nlen = htobe32(length); debug_info("sending %d bytes", length); - service_send(client->parent, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); + service_send(client->parent, (const char*)&nlen, sizeof(nlen), &bytes); if (bytes == sizeof(nlen)) { - service_send(client->parent, content, length, (uint32_t*)&bytes); + service_send(client->parent, content, length, &bytes); if (bytes > 0) { debug_info("sent %d bytes", bytes); debug_plist(plist); - if ((uint32_t)bytes == length) { + if (bytes == length) { res = PROPERTY_LIST_SERVICE_E_SUCCESS; } else { debug_info("ERROR: Could not send all data (%d of %d)!", bytes, length); @@ -145,7 +149,6 @@ static property_list_service_error_t internal_plist_send(property_list_service_c } free(content); - return res; } @@ -170,6 +173,8 @@ LIBIMOBILEDEVICE_API property_list_service_error_t property_list_service_send_bi * * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or *plist is NULL, + * PROPERTY_LIST_SERVICE_E_NOT_ENOUGH_DATA when not enough data + * received, PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT when the connection times out, * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR @@ -187,65 +192,64 @@ static property_list_service_error_t internal_plist_receive_timeout(property_lis *plist = NULL; service_error_t serr = service_receive_with_timeout(client->parent, (char*)&pktlen, sizeof(pktlen), &bytes, timeout); - if ((serr == SERVICE_E_SUCCESS) && (bytes == 0)) { - return PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT; + if (serr != SERVICE_E_SUCCESS) { + debug_info("initial read failed!"); + return service_to_property_list_service_error(serr); } + debug_info("initial read=%i", bytes); - if (bytes < 4) { - debug_info("initial read failed!"); - return PROPERTY_LIST_SERVICE_E_MUX_ERROR; - } else { - uint32_t curlen = 0; - char *content = NULL; - pktlen = be32toh(pktlen); - debug_info("%d bytes following", pktlen); - content = (char*)malloc(pktlen); - if (!content) { - debug_info("out of memory when allocating %d bytes", pktlen); - return PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; - } + uint32_t curlen = 0; + char *content = NULL; - while (curlen < pktlen) { - service_receive(client->parent, content+curlen, pktlen-curlen, &bytes); - if (bytes <= 0) { - res = PROPERTY_LIST_SERVICE_E_MUX_ERROR; - break; - } - debug_info("received %d bytes", bytes); - curlen += bytes; - } - if (curlen < pktlen) { - debug_info("received incomplete packet (%d of %d bytes)", curlen, pktlen); - if (curlen > 0) { - debug_info("incomplete packet following:"); - debug_buffer(content, curlen); - } - free(content); - return res; - } - if ((pktlen > 8) && !memcmp(content, "bplist00", 8)) { - plist_from_bin(content, pktlen, plist); - } else if ((pktlen > 5) && !memcmp(content, "= 0) && (content[bytes] < 0x20) && (content[bytes] != 0x09) && (content[bytes] != 0x0a) && (content[bytes] != 0x0d)) - content[bytes] = 0x20; - } - plist_from_xml(content, pktlen, plist); - } else { - debug_info("WARNING: received unexpected non-plist content"); - debug_buffer(content, pktlen); + pktlen = be32toh(pktlen); + debug_info("%d bytes following", pktlen); + content = (char*)malloc(pktlen); + if (!content) { + debug_info("out of memory when allocating %d bytes", pktlen); + return PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; + } + + while (curlen < pktlen) { + serr = service_receive(client->parent, content+curlen, pktlen-curlen, &bytes); + if (serr != SERVICE_E_SUCCESS) { + res = service_to_property_list_service_error(serr); + break; } - if (*plist) { - debug_plist(*plist); - res = PROPERTY_LIST_SERVICE_E_SUCCESS; - } else { - res = PROPERTY_LIST_SERVICE_E_PLIST_ERROR; + debug_info("received %d bytes", bytes); + curlen += bytes; + } + if (curlen < pktlen) { + debug_info("received incomplete packet (%d of %d bytes)", curlen, pktlen); + if (curlen > 0) { + debug_info("incomplete packet following:"); + debug_buffer(content, curlen); } free(content); - content = NULL; + return res; } + if ((pktlen > 8) && !memcmp(content, "bplist00", 8)) { + plist_from_bin(content, pktlen, plist); + } else if ((pktlen > 5) && !memcmp(content, "= 0) && (content[bytes] < 0x20) && (content[bytes] != 0x09) && (content[bytes] != 0x0a) && (content[bytes] != 0x0d)) + content[bytes] = 0x20; + } + plist_from_xml(content, pktlen, plist); + } else { + debug_info("WARNING: received unexpected non-plist content"); + debug_buffer(content, pktlen); + } + if (*plist) { + debug_plist(*plist); + res = PROPERTY_LIST_SERVICE_E_SUCCESS; + } else { + res = PROPERTY_LIST_SERVICE_E_PLIST_ERROR; + } + free(content); + content = NULL; + return res; } -- cgit v1.1-32-gdbae