From fcaca86f96ced10c37a33541c14b6727b863c8dc Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 28 Aug 2019 16:01:34 +0300 Subject: [PATCH 1/4] fix: add timeout when receiving message from connection All socket connections were changed and now are started in ssl mode. This changes the way messages are sent and received from sockets. As a result, `timeout` option is not anymore respected when receiving messages from socket. However, the messages now are received only via methods from mobile device lib. As there isn't a built-in method in mobile device that can work with timeout, we implemented timeout mechanism using new thread. `AMDServiceConnectionReceive` blocks the current thread when application is not running on device. After the provided timeout, the socket connection is invalidated and this way the current thread is freed. --- IOSDeviceLib/Declarations.h | 1 + IOSDeviceLib/IOSDeviceLib.cpp | 4 ++-- IOSDeviceLib/SocketHelper.cpp | 19 ++++++++++++++++++- IOSDeviceLib/SocketHelper.h | 2 +- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/IOSDeviceLib/Declarations.h b/IOSDeviceLib/Declarations.h index 0c9a851..e564d84 100644 --- a/IOSDeviceLib/Declarations.h +++ b/IOSDeviceLib/Declarations.h @@ -267,6 +267,7 @@ extern "C" { CFSocketNativeHandle AMDServiceConnectionGetSocket(ServiceConnRef con); long AMDServiceConnectionReceive(ServiceConnRef, void *, long); + void AMDServiceConnectionInvalidate(ServiceConnRef); long AMDServiceConnectionSendMessage(ServiceConnRef serviceConnection, CFDictionaryRef message, CFPropertyListFormat format); unsigned AMDeviceSecureStartService(AMDeviceRef device, CFStringRef service_name, unsigned int *unknown, ServiceConnRef * handle); unsigned AMDeviceNotificationSubscribe(void(*f)(const DevicePointer*), long, long, long, HANDLE*); diff --git a/IOSDeviceLib/IOSDeviceLib.cpp b/IOSDeviceLib/IOSDeviceLib.cpp index 65927bd..0061b08 100644 --- a/IOSDeviceLib/IOSDeviceLib.cpp +++ b/IOSDeviceLib/IOSDeviceLib.cpp @@ -1007,7 +1007,7 @@ void get_application_infos(std::string device_identifier, std::string method_id) std::vector livesync_app_infos; while (true) { - std::map dict = receive_con_message(serviceInfo.connection); + std::map dict = receive_con_message(serviceInfo.connection, device_identifier, method_id, 0); PRINT_ERROR_AND_RETURN_IF_FAILED_RESULT(dict.count(kErrorKey), boost::any_cast(dict[kErrorKey]).c_str(), device_identifier, method_id); if (dict.empty() || (dict.count(kStatusKey) && has_complete_status(dict))) { @@ -1181,7 +1181,7 @@ void await_notification_response(std::string device_identifier, AwaitNotificatio PRINT_ERROR_AND_RETURN_IF_FAILED_RESULT(connection == nullptr, invalid_connection_error_message.c_str(), device_identifier, method_id); ServiceInfo currentNotificationProxy = devices[device_identifier].services[kNotificationProxy]; - std::map response = receive_con_message(connection); + std::map response = receive_con_message(connection, device_identifier, method_id, await_notification_response_info.timeout); if (response.size()) { PRINT_ERROR_AND_RETURN_IF_FAILED_RESULT(response.count(kErrorKey), boost::any_cast(response[kErrorKey]).c_str(), device_identifier, method_id); diff --git a/IOSDeviceLib/SocketHelper.cpp b/IOSDeviceLib/SocketHelper.cpp index b6995e9..396edf7 100644 --- a/IOSDeviceLib/SocketHelper.cpp +++ b/IOSDeviceLib/SocketHelper.cpp @@ -7,10 +7,26 @@ #include "PlistCpp/Plist.hpp" #include "PlistCpp/PlistDate.hpp" +void setTimeout(std::function operation, int timeout) { + std::thread([=]() { + std::this_thread::sleep_for(std::chrono::milliseconds(timeout * 1000)); + operation(); + }).detach(); +} + std::mutex receive_con_message_mutex; -std::map receive_con_message(ServiceConnRef con) +std::map receive_con_message(ServiceConnRef con, std::string device_identifier, std::string method_id, int timeout) { receive_con_message_mutex.lock(); + + bool isSuccessful = false; + + setTimeout([=]() { + if (!isSuccessful) { + AMDServiceConnectionInvalidate(con); + } + }, timeout); + std::map dict; char *buffer = new char[4]; int bytes_read = AMDServiceConnectionReceive(con, buffer, 4); @@ -23,6 +39,7 @@ std::map receive_con_message(ServiceConnRef con) if (bytes_read > 0) { Plist::readPlist(buffer, res, dict); + isSuccessful = true; } } diff --git a/IOSDeviceLib/SocketHelper.h b/IOSDeviceLib/SocketHelper.h index f0edb6f..789b900 100644 --- a/IOSDeviceLib/SocketHelper.h +++ b/IOSDeviceLib/SocketHelper.h @@ -41,7 +41,7 @@ LengthEncodedMessage get_message_with_encoded_length(const char* message, long l int send_message(const char* message, SOCKET socket, long long length = -1); int send_message(std::string message, SOCKET socket, long long length = -1); long send_con_message(HANDLE* serviceConnection, CFDictionaryRef message); -std::map receive_con_message(HANDLE* con); +std::map receive_con_message(HANDLE* con, std::string device_identifier, std::string method_id, int timeout); std::map receive_message(SOCKET socket, int timeout = 5); std::string receive_message_raw(SOCKET socket, int size = 1000); From df52dfe889a3ea78ac2b1bd16ddbe5f2d736d8cc Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 28 Aug 2019 16:03:17 +0300 Subject: [PATCH 2/4] fix: fix typo and remove not needed caching of house arrest service --- IOSDeviceLib/IOSDeviceLib.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/IOSDeviceLib/IOSDeviceLib.cpp b/IOSDeviceLib/IOSDeviceLib.cpp index 0061b08..4361896 100644 --- a/IOSDeviceLib/IOSDeviceLib.cpp +++ b/IOSDeviceLib/IOSDeviceLib.cpp @@ -210,11 +210,6 @@ void cleanup_file_resources(const std::string& device_identifier, const std::str AFCConnectionClose(afc_connection_to_close); devices[device_identifier].apps_cache.erase(application_identifier); } - - if (devices[device_identifier].services.count(kHouseArrest)) - { - devices[device_identifier].services.erase(kHouseArrest); - } } void cleanup_file_resources(const std::string& device_identifier) @@ -982,13 +977,13 @@ void get_application_infos(std::string device_identifier, std::string method_id) CFStringRef cf_app_type_value = create_CFString("User"); const void *client_opts_values_arr[] = { cf_app_type_value, cf_return_attributes_array }; - CFDictionaryRef clinet_opts_dict = CFDictionaryCreate(NULL, client_opts_keys_arr, client_opts_values_arr, 2, NULL, NULL); + CFDictionaryRef client_opts_dict = CFDictionaryCreate(NULL, client_opts_keys_arr, client_opts_values_arr, 2, NULL, NULL); CFStringRef cf_command_key = create_CFString("Command"); CFStringRef cf_client_options_key = create_CFString("ClientOptions"); const void *keys_arr[] = { cf_command_key, cf_client_options_key }; CFStringRef cf_command_value = create_CFString("Browse"); - const void *values_arr[] = { cf_command_value, clinet_opts_dict }; + const void *values_arr[] = { cf_command_value, client_opts_dict }; CFDictionaryRef dict_command = CFDictionaryCreate(NULL, keys_arr, values_arr, 2, NULL, NULL); send_con_message(serviceInfo.connection, dict_command); @@ -998,7 +993,7 @@ void get_application_infos(std::string device_identifier, std::string method_id) CFRelease(cf_app_type_key); CFRelease(cf_return_attrs_key); CFRelease(cf_app_type_value); - CFRelease(clinet_opts_dict); + CFRelease(client_opts_dict); CFRelease(cf_command_key); CFRelease(cf_client_options_key); CFRelease(cf_command_value); From 462e68a912d8c4da6b4a856db435478ca20774eb Mon Sep 17 00:00:00 2001 From: Fatme Date: Wed, 28 Aug 2019 16:46:05 +0300 Subject: [PATCH 3/4] Apply suggestions from code review Co-Authored-By: Dimitar Tachev --- IOSDeviceLib/Declarations.h | 2 +- IOSDeviceLib/IOSDeviceLib.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/IOSDeviceLib/Declarations.h b/IOSDeviceLib/Declarations.h index e564d84..44cac91 100644 --- a/IOSDeviceLib/Declarations.h +++ b/IOSDeviceLib/Declarations.h @@ -267,7 +267,7 @@ extern "C" { CFSocketNativeHandle AMDServiceConnectionGetSocket(ServiceConnRef con); long AMDServiceConnectionReceive(ServiceConnRef, void *, long); - void AMDServiceConnectionInvalidate(ServiceConnRef); + void AMDServiceConnectionInvalidate(ServiceConnRef); long AMDServiceConnectionSendMessage(ServiceConnRef serviceConnection, CFDictionaryRef message, CFPropertyListFormat format); unsigned AMDeviceSecureStartService(AMDeviceRef device, CFStringRef service_name, unsigned int *unknown, ServiceConnRef * handle); unsigned AMDeviceNotificationSubscribe(void(*f)(const DevicePointer*), long, long, long, HANDLE*); diff --git a/IOSDeviceLib/IOSDeviceLib.cpp b/IOSDeviceLib/IOSDeviceLib.cpp index 4361896..5a86e38 100644 --- a/IOSDeviceLib/IOSDeviceLib.cpp +++ b/IOSDeviceLib/IOSDeviceLib.cpp @@ -1002,7 +1002,7 @@ void get_application_infos(std::string device_identifier, std::string method_id) std::vector livesync_app_infos; while (true) { - std::map dict = receive_con_message(serviceInfo.connection, device_identifier, method_id, 0); + std::map dict = receive_con_message(serviceInfo.connection, device_identifier, method_id, 10); PRINT_ERROR_AND_RETURN_IF_FAILED_RESULT(dict.count(kErrorKey), boost::any_cast(dict[kErrorKey]).c_str(), device_identifier, method_id); if (dict.empty() || (dict.count(kStatusKey) && has_complete_status(dict))) { From 08df456cf8c156086e2c37b6e4865de15ef84797 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 28 Aug 2019 17:02:22 +0300 Subject: [PATCH 4/4] fix: fix PR comments and bump version --- IOSDeviceLib/SocketHelper.cpp | 12 +++++++----- package.json | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/IOSDeviceLib/SocketHelper.cpp b/IOSDeviceLib/SocketHelper.cpp index 396edf7..68c5e81 100644 --- a/IOSDeviceLib/SocketHelper.cpp +++ b/IOSDeviceLib/SocketHelper.cpp @@ -21,11 +21,13 @@ std::map receive_con_message(ServiceConnRef con, std::s bool isSuccessful = false; - setTimeout([=]() { - if (!isSuccessful) { - AMDServiceConnectionInvalidate(con); - } - }, timeout); + if (timeout > 0) { + setTimeout([=]() { + if (!isSuccessful) { + AMDServiceConnectionInvalidate(con); + } + }, timeout); + } std::map dict; char *buffer = new char[4]; diff --git a/package.json b/package.json index 21995bf..cdc35c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ios-device-lib", - "version": "0.7.0", + "version": "0.7.1", "description": "", "types": "./typings/ios-device-lib.d.ts", "main": "index.js",