summaryrefslogtreecommitdiffstats
path: root/src/property_list_service.c
diff options
context:
space:
mode:
authorGravatar DanyL2019-06-13 02:01:04 +0300
committerGravatar Nikias Bassen2019-06-13 01:41:20 +0200
commit4d8b89223cbc9f530cc650ab5131c09eab1af258 (patch)
treee63216393208c07ae83c7b8eba5e0a9546de4fef /src/property_list_service.c
parent6edc36fccb52a963c9ebfbb44ba7b91570e0fd06 (diff)
downloadlibimobiledevice-4d8b89223cbc9f530cc650ab5131c09eab1af258.tar.gz
libimobiledevice-4d8b89223cbc9f530cc650ab5131c09eab1af258.tar.bz2
Timeout support for SSL connections and better timeout handeling.
Diffstat (limited to 'src/property_list_service.c')
-rw-r--r--src/property_list_service.c116
1 files changed, 60 insertions, 56 deletions
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
48 return PROPERTY_LIST_SERVICE_E_MUX_ERROR; 48 return PROPERTY_LIST_SERVICE_E_MUX_ERROR;
49 case SERVICE_E_SSL_ERROR: 49 case SERVICE_E_SSL_ERROR:
50 return PROPERTY_LIST_SERVICE_E_SSL_ERROR; 50 return PROPERTY_LIST_SERVICE_E_SSL_ERROR;
51 case SERIVCE_E_NOT_ENOUGH_DATA:
52 return PROPERTY_LIST_SERVICE_E_NOT_ENOUGH_DATA;
53 case SERVICE_E_TIMEOUT:
54 return PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT;
51 default: 55 default:
52 break; 56 break;
53 } 57 }
@@ -108,7 +112,7 @@ static property_list_service_error_t internal_plist_send(property_list_service_c
108 char *content = NULL; 112 char *content = NULL;
109 uint32_t length = 0; 113 uint32_t length = 0;
110 uint32_t nlen = 0; 114 uint32_t nlen = 0;
111 int bytes = 0; 115 uint32_t bytes = 0;
112 116
113 if (!client || (client && !client->parent) || !plist) { 117 if (!client || (client && !client->parent) || !plist) {
114 return PROPERTY_LIST_SERVICE_E_INVALID_ARG; 118 return PROPERTY_LIST_SERVICE_E_INVALID_ARG;
@@ -126,13 +130,13 @@ static property_list_service_error_t internal_plist_send(property_list_service_c
126 130
127 nlen = htobe32(length); 131 nlen = htobe32(length);
128 debug_info("sending %d bytes", length); 132 debug_info("sending %d bytes", length);
129 service_send(client->parent, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); 133 service_send(client->parent, (const char*)&nlen, sizeof(nlen), &bytes);
130 if (bytes == sizeof(nlen)) { 134 if (bytes == sizeof(nlen)) {
131 service_send(client->parent, content, length, (uint32_t*)&bytes); 135 service_send(client->parent, content, length, &bytes);
132 if (bytes > 0) { 136 if (bytes > 0) {
133 debug_info("sent %d bytes", bytes); 137 debug_info("sent %d bytes", bytes);
134 debug_plist(plist); 138 debug_plist(plist);
135 if ((uint32_t)bytes == length) { 139 if (bytes == length) {
136 res = PROPERTY_LIST_SERVICE_E_SUCCESS; 140 res = PROPERTY_LIST_SERVICE_E_SUCCESS;
137 } else { 141 } else {
138 debug_info("ERROR: Could not send all data (%d of %d)!", bytes, length); 142 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
145 } 149 }
146 150
147 free(content); 151 free(content);
148
149 return res; 152 return res;
150} 153}
151 154
@@ -170,6 +173,8 @@ LIBIMOBILEDEVICE_API property_list_service_error_t property_list_service_send_bi
170 * 173 *
171 * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, 174 * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success,
172 * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or *plist is NULL, 175 * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or *plist is NULL,
176 * PROPERTY_LIST_SERVICE_E_NOT_ENOUGH_DATA when not enough data
177 * received, PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT when the connection times out,
173 * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be 178 * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be
174 * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a 179 * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a
175 * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR 180 * 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
187 192
188 *plist = NULL; 193 *plist = NULL;
189 service_error_t serr = service_receive_with_timeout(client->parent, (char*)&pktlen, sizeof(pktlen), &bytes, timeout); 194 service_error_t serr = service_receive_with_timeout(client->parent, (char*)&pktlen, sizeof(pktlen), &bytes, timeout);
190 if ((serr == SERVICE_E_SUCCESS) && (bytes == 0)) { 195 if (serr != SERVICE_E_SUCCESS) {
191 return PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT; 196 debug_info("initial read failed!");
197 return service_to_property_list_service_error(serr);
192 } 198 }
199
193 debug_info("initial read=%i", bytes); 200 debug_info("initial read=%i", bytes);
194 if (bytes < 4) {
195 debug_info("initial read failed!");
196 return PROPERTY_LIST_SERVICE_E_MUX_ERROR;
197 } else {
198 uint32_t curlen = 0;
199 char *content = NULL;
200 201
201 pktlen = be32toh(pktlen); 202 uint32_t curlen = 0;
202 debug_info("%d bytes following", pktlen); 203 char *content = NULL;
203 content = (char*)malloc(pktlen);
204 if (!content) {
205 debug_info("out of memory when allocating %d bytes", pktlen);
206 return PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR;
207 }
208 204
209 while (curlen < pktlen) { 205 pktlen = be32toh(pktlen);
210 service_receive(client->parent, content+curlen, pktlen-curlen, &bytes); 206 debug_info("%d bytes following", pktlen);
211 if (bytes <= 0) { 207 content = (char*)malloc(pktlen);
212 res = PROPERTY_LIST_SERVICE_E_MUX_ERROR; 208 if (!content) {
213 break; 209 debug_info("out of memory when allocating %d bytes", pktlen);
214 } 210 return PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR;
215 debug_info("received %d bytes", bytes); 211 }
216 curlen += bytes; 212
217 } 213 while (curlen < pktlen) {
218 if (curlen < pktlen) { 214 serr = service_receive(client->parent, content+curlen, pktlen-curlen, &bytes);
219 debug_info("received incomplete packet (%d of %d bytes)", curlen, pktlen); 215 if (serr != SERVICE_E_SUCCESS) {
220 if (curlen > 0) { 216 res = service_to_property_list_service_error(serr);
221 debug_info("incomplete packet following:"); 217 break;
222 debug_buffer(content, curlen);
223 }
224 free(content);
225 return res;
226 }
227 if ((pktlen > 8) && !memcmp(content, "bplist00", 8)) {
228 plist_from_bin(content, pktlen, plist);
229 } else if ((pktlen > 5) && !memcmp(content, "<?xml", 5)) {
230 /* iOS 4.3+ hack: plist data might contain invalid characters, thus we convert those to spaces */
231 for (bytes = 0; bytes < pktlen-1; bytes++) {
232 if ((content[bytes] >= 0) && (content[bytes] < 0x20) && (content[bytes] != 0x09) && (content[bytes] != 0x0a) && (content[bytes] != 0x0d))
233 content[bytes] = 0x20;
234 }
235 plist_from_xml(content, pktlen, plist);
236 } else {
237 debug_info("WARNING: received unexpected non-plist content");
238 debug_buffer(content, pktlen);
239 } 218 }
240 if (*plist) { 219 debug_info("received %d bytes", bytes);
241 debug_plist(*plist); 220 curlen += bytes;
242 res = PROPERTY_LIST_SERVICE_E_SUCCESS; 221 }
243 } else { 222 if (curlen < pktlen) {
244 res = PROPERTY_LIST_SERVICE_E_PLIST_ERROR; 223 debug_info("received incomplete packet (%d of %d bytes)", curlen, pktlen);
224 if (curlen > 0) {
225 debug_info("incomplete packet following:");
226 debug_buffer(content, curlen);
245 } 227 }
246 free(content); 228 free(content);
247 content = NULL; 229 return res;
248 } 230 }
231 if ((pktlen > 8) && !memcmp(content, "bplist00", 8)) {
232 plist_from_bin(content, pktlen, plist);
233 } else if ((pktlen > 5) && !memcmp(content, "<?xml", 5)) {
234 /* iOS 4.3+ hack: plist data might contain invalid characters, thus we convert those to spaces */
235 for (bytes = 0; bytes < pktlen-1; bytes++) {
236 if ((content[bytes] >= 0) && (content[bytes] < 0x20) && (content[bytes] != 0x09) && (content[bytes] != 0x0a) && (content[bytes] != 0x0d))
237 content[bytes] = 0x20;
238 }
239 plist_from_xml(content, pktlen, plist);
240 } else {
241 debug_info("WARNING: received unexpected non-plist content");
242 debug_buffer(content, pktlen);
243 }
244 if (*plist) {
245 debug_plist(*plist);
246 res = PROPERTY_LIST_SERVICE_E_SUCCESS;
247 } else {
248 res = PROPERTY_LIST_SERVICE_E_PLIST_ERROR;
249 }
250 free(content);
251 content = NULL;
252
249 return res; 253 return res;
250} 254}
251 255