diff options
| -rw-r--r-- | tools/idevicedebugserverproxy.c | 117 |
1 files changed, 46 insertions, 71 deletions
diff --git a/tools/idevicedebugserverproxy.c b/tools/idevicedebugserverproxy.c index 475749f..2209abc 100644 --- a/tools/idevicedebugserverproxy.c +++ b/tools/idevicedebugserverproxy.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <signal.h> | 26 | #include <signal.h> |
| 27 | 27 | ||
| 28 | #include <libimobiledevice/libimobiledevice.h> | 28 | #include <libimobiledevice/libimobiledevice.h> |
| 29 | #include <libimobiledevice/lockdown.h> | 29 | #include <libimobiledevice/debugserver.h> |
| 30 | 30 | ||
| 31 | #include "common/socket.h" | 31 | #include "common/socket.h" |
| 32 | #include "common/thread.h" | 32 | #include "common/thread.h" |
| @@ -41,16 +41,30 @@ typedef struct { | |||
| 41 | int server_fd; | 41 | int server_fd; |
| 42 | int client_fd; | 42 | int client_fd; |
| 43 | uint16_t local_port; | 43 | uint16_t local_port; |
| 44 | uint16_t remote_port; | 44 | idevice_t device; |
| 45 | idevice_connection_t device_connection; | 45 | debugserver_client_t debugserver_client; |
| 46 | volatile int stop_ctod; | 46 | volatile int stop_ctod; |
| 47 | volatile int stop_dtoc; | 47 | volatile int stop_dtoc; |
| 48 | } socket_info_t; | 48 | } socket_info_t; |
| 49 | 49 | ||
| 50 | static socket_info_t global_socket_info; | ||
| 51 | |||
| 50 | static void clean_exit(int sig) | 52 | static void clean_exit(int sig) |
| 51 | { | 53 | { |
| 52 | fprintf(stderr, "Exiting...\n"); | 54 | if (quit_flag == 0) |
| 55 | fprintf(stderr, "Setting quit status. Cancel again to quit server.\n"); | ||
| 56 | else | ||
| 57 | fprintf(stderr, "Exiting...\n"); | ||
| 58 | |||
| 53 | quit_flag++; | 59 | quit_flag++; |
| 60 | |||
| 61 | /* shutdown server socket if we have to terminate to unblock the server loop */ | ||
| 62 | if (quit_flag > 1) { | ||
| 63 | if (global_socket_info.server_fd > 0) { | ||
| 64 | socket_shutdown(global_socket_info.server_fd, SHUT_RDWR); | ||
| 65 | socket_close(global_socket_info.server_fd); | ||
| 66 | } | ||
| 67 | } | ||
| 54 | } | 68 | } |
| 55 | 69 | ||
| 56 | static void print_usage(int argc, char **argv) | 70 | static void print_usage(int argc, char **argv) |
| @@ -83,7 +97,7 @@ static void *thread_device_to_client(void *data) | |||
| 83 | while (!quit_flag && !socket_info->stop_dtoc && socket_info->client_fd > 0 && socket_info->server_fd > 0) { | 97 | while (!quit_flag && !socket_info->stop_dtoc && socket_info->client_fd > 0 && socket_info->server_fd > 0) { |
| 84 | debug("%s: receiving data from device...\n", __func__); | 98 | debug("%s: receiving data from device...\n", __func__); |
| 85 | 99 | ||
| 86 | res = idevice_connection_receive_timeout(socket_info->device_connection, buffer, sizeof(buffer), (uint32_t*)&recv_len, 5000); | 100 | res = debugserver_client_receive_with_timeout(socket_info->debugserver_client, buffer, sizeof(buffer), (uint32_t*)&recv_len, 5000); |
| 87 | 101 | ||
| 88 | if (recv_len <= 0) { | 102 | if (recv_len <= 0) { |
| 89 | if (recv_len == 0 && res == IDEVICE_E_SUCCESS) { | 103 | if (recv_len == 0 && res == IDEVICE_E_SUCCESS) { |
| @@ -161,7 +175,7 @@ static void *thread_client_to_device(void *data) | |||
| 161 | } else { | 175 | } else { |
| 162 | /* forward data to device */ | 176 | /* forward data to device */ |
| 163 | debug("%s: sending data to device...\n", __func__); | 177 | debug("%s: sending data to device...\n", __func__); |
| 164 | res = idevice_connection_send(socket_info->device_connection, buffer, recv_len, (uint32_t*)&sent); | 178 | res = debugserver_client_send(socket_info->debugserver_client, buffer, recv_len, (uint32_t*)&sent); |
| 165 | 179 | ||
| 166 | if (sent < recv_len || res != IDEVICE_E_SUCCESS) { | 180 | if (sent < recv_len || res != IDEVICE_E_SUCCESS) { |
| 167 | if (sent <= 0) { | 181 | if (sent <= 0) { |
| @@ -194,11 +208,18 @@ static void *thread_client_to_device(void *data) | |||
| 194 | 208 | ||
| 195 | static void* connection_handler(void* data) | 209 | static void* connection_handler(void* data) |
| 196 | { | 210 | { |
| 211 | debugserver_error_t derr = DEBUGSERVER_E_SUCCESS; | ||
| 197 | socket_info_t* socket_info = (socket_info_t*)data; | 212 | socket_info_t* socket_info = (socket_info_t*)data; |
| 198 | thread_t ctod; | 213 | thread_t ctod; |
| 199 | 214 | ||
| 200 | debug("%s: client_fd = %d\n", __func__, socket_info->client_fd); | 215 | debug("%s: client_fd = %d\n", __func__, socket_info->client_fd); |
| 201 | 216 | ||
| 217 | derr = debugserver_client_start_service(socket_info->device, &socket_info->debugserver_client, "idevicedebugserverproxy"); | ||
| 218 | if (derr != DEBUGSERVER_E_SUCCESS) { | ||
| 219 | fprintf(stderr, "Could not start debugserver on device!\nPlease make sure to mount a developer disk image first.\n"); | ||
| 220 | return NULL; | ||
| 221 | } | ||
| 222 | |||
| 202 | /* spawn client to device thread */ | 223 | /* spawn client to device thread */ |
| 203 | socket_info->stop_ctod = 0; | 224 | socket_info->stop_ctod = 0; |
| 204 | if (thread_new(&ctod, thread_client_to_device, data) != 0) { | 225 | if (thread_new(&ctod, thread_client_to_device, data) != 0) { |
| @@ -209,29 +230,23 @@ static void* connection_handler(void* data) | |||
| 209 | thread_join(ctod); | 230 | thread_join(ctod); |
| 210 | thread_free(ctod); | 231 | thread_free(ctod); |
| 211 | 232 | ||
| 233 | debug("%s: shutting down...\n", __func__); | ||
| 234 | |||
| 235 | debugserver_client_free(socket_info->debugserver_client); | ||
| 236 | socket_info->debugserver_client = NULL; | ||
| 237 | |||
| 212 | /* shutdown client socket */ | 238 | /* shutdown client socket */ |
| 213 | socket_shutdown(socket_info->client_fd, SHUT_RDWR); | 239 | socket_shutdown(socket_info->client_fd, SHUT_RDWR); |
| 214 | socket_close(socket_info->client_fd); | 240 | socket_close(socket_info->client_fd); |
| 215 | 241 | ||
| 216 | /* shutdown server socket if we have to terminate to unblock the server loop */ | ||
| 217 | if (quit_flag) { | ||
| 218 | socket_shutdown(socket_info->server_fd, SHUT_RDWR); | ||
| 219 | socket_close(socket_info->server_fd); | ||
| 220 | } | ||
| 221 | |||
| 222 | return NULL; | 242 | return NULL; |
| 223 | } | 243 | } |
| 224 | 244 | ||
| 225 | int main(int argc, char *argv[]) | 245 | int main(int argc, char *argv[]) |
| 226 | { | 246 | { |
| 227 | lockdownd_client_t lockdown = NULL; | ||
| 228 | lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR; | ||
| 229 | idevice_t device = NULL; | ||
| 230 | idevice_connection_t connection = NULL; | ||
| 231 | idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; | 247 | idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; |
| 232 | thread_t th; | 248 | thread_t th; |
| 233 | const char* udid = NULL; | 249 | const char* udid = NULL; |
| 234 | lockdownd_service_descriptor_t service = NULL; | ||
| 235 | uint16_t local_port = 0; | 250 | uint16_t local_port = 0; |
| 236 | int result = EXIT_SUCCESS; | 251 | int result = EXIT_SUCCESS; |
| 237 | int i; | 252 | int i; |
| @@ -282,8 +297,11 @@ int main(int argc, char *argv[]) | |||
| 282 | goto leave_cleanup; | 297 | goto leave_cleanup; |
| 283 | } | 298 | } |
| 284 | 299 | ||
| 300 | /* setup and create socket endpoint */ | ||
| 301 | global_socket_info.local_port = local_port; | ||
| 302 | |||
| 285 | /* start services and connect to device */ | 303 | /* start services and connect to device */ |
| 286 | ret = idevice_new(&device, udid); | 304 | ret = idevice_new(&global_socket_info.device, udid); |
| 287 | if (ret != IDEVICE_E_SUCCESS) { | 305 | if (ret != IDEVICE_E_SUCCESS) { |
| 288 | if (udid) { | 306 | if (udid) { |
| 289 | fprintf(stderr, "No device found with udid %s, is it plugged in?\n", udid); | 307 | fprintf(stderr, "No device found with udid %s, is it plugged in?\n", udid); |
| @@ -294,66 +312,29 @@ int main(int argc, char *argv[]) | |||
| 294 | goto leave_cleanup; | 312 | goto leave_cleanup; |
| 295 | } | 313 | } |
| 296 | 314 | ||
| 297 | if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &lockdown, "idevicedebugserverproxy"))) { | ||
| 298 | fprintf(stderr, "ERROR: Could not connect to lockdownd, error code %d\n", ldret); | ||
| 299 | result = EXIT_FAILURE; | ||
| 300 | goto leave_cleanup; | ||
| 301 | } | ||
| 302 | |||
| 303 | if ((lockdownd_start_service(lockdown, "com.apple.debugserver", &service) != LOCKDOWN_E_SUCCESS) || !service || !service->port) { | ||
| 304 | fprintf(stderr, "Could not start com.apple.debugserver!\nPlease make sure to mount the developer disk image first.\n"); | ||
| 305 | result = EXIT_FAILURE; | ||
| 306 | goto leave_cleanup; | ||
| 307 | } | ||
| 308 | |||
| 309 | if (idevice_connect(device, service->port, &connection) != IDEVICE_E_SUCCESS) { | ||
| 310 | fprintf(stderr, "Connection to debugserver port %d failed!\n", (int)service->port); | ||
| 311 | result = EXIT_FAILURE; | ||
| 312 | goto leave_cleanup; | ||
| 313 | } | ||
| 314 | |||
| 315 | /* free lockdown connection if running as it is not needed anymore */ | ||
| 316 | if (lockdown) { | ||
| 317 | lockdownd_client_free(lockdown); | ||
| 318 | lockdown = NULL; | ||
| 319 | } | ||
| 320 | |||
| 321 | /* setup and create socket endpoint */ | ||
| 322 | socket_info_t socket_info; | ||
| 323 | |||
| 324 | socket_info.device_connection = connection; | ||
| 325 | socket_info.local_port = local_port; | ||
| 326 | socket_info.remote_port = service->port; | ||
| 327 | |||
| 328 | if (service) { | ||
| 329 | lockdownd_service_descriptor_free(service); | ||
| 330 | service = NULL; | ||
| 331 | } | ||
| 332 | |||
| 333 | /* create local socket */ | 315 | /* create local socket */ |
| 334 | socket_info.server_fd = socket_create(socket_info.local_port); | 316 | global_socket_info.server_fd = socket_create(global_socket_info.local_port); |
| 335 | if (socket_info.server_fd < 0) { | 317 | if (global_socket_info.server_fd < 0) { |
| 336 | fprintf(stderr, "Could not create socket\n"); | 318 | fprintf(stderr, "Could not create socket\n"); |
| 337 | result = EXIT_FAILURE; | 319 | result = EXIT_FAILURE; |
| 338 | goto leave_cleanup; | 320 | goto leave_cleanup; |
| 339 | } | 321 | } |
| 340 | 322 | ||
| 341 | while (!quit_flag) { | 323 | while (!quit_flag) { |
| 342 | debug("%s: Waiting for connection on local port %d\n", __func__, socket_info.local_port); | 324 | debug("%s: Waiting for connection on local port %d\n", __func__, global_socket_info.local_port); |
| 343 | 325 | ||
| 344 | /* wait for client */ | 326 | /* wait for client */ |
| 345 | socket_info.client_fd = socket_accept(socket_info.server_fd, socket_info.local_port); | 327 | global_socket_info.client_fd = socket_accept(global_socket_info.server_fd, global_socket_info.local_port); |
| 346 | if (socket_info.client_fd < 0) { | 328 | if (global_socket_info.client_fd < 0) { |
| 347 | debug("%s: Continuing...\n", __func__); | ||
| 348 | continue; | 329 | continue; |
| 349 | } | 330 | } |
| 350 | 331 | ||
| 351 | debug("%s: Handling new client connection...\n", __func__); | 332 | debug("%s: Handling new client connection...\n", __func__); |
| 352 | 333 | ||
| 353 | if (thread_new(&th, connection_handler, (void*)&socket_info) != 0) { | 334 | if (thread_new(&th, connection_handler, (void*)&global_socket_info) != 0) { |
| 354 | fprintf(stderr, "Could not start connection handler.\n"); | 335 | fprintf(stderr, "Could not start connection handler.\n"); |
| 355 | socket_shutdown(socket_info.server_fd, SHUT_RDWR); | 336 | socket_shutdown(global_socket_info.server_fd, SHUT_RDWR); |
| 356 | socket_close(socket_info.server_fd); | 337 | socket_close(global_socket_info.server_fd); |
| 357 | continue; | 338 | continue; |
| 358 | } | 339 | } |
| 359 | 340 | ||
| @@ -364,14 +345,8 @@ int main(int argc, char *argv[]) | |||
| 364 | debug("%s: Shutting down debugserver proxy...\n", __func__); | 345 | debug("%s: Shutting down debugserver proxy...\n", __func__); |
| 365 | 346 | ||
| 366 | leave_cleanup: | 347 | leave_cleanup: |
| 367 | if (connection) { | 348 | if (global_socket_info.device) { |
| 368 | idevice_disconnect(connection); | 349 | idevice_free(global_socket_info.device); |
| 369 | } | ||
| 370 | if (lockdown) { | ||
| 371 | lockdownd_client_free(lockdown); | ||
| 372 | } | ||
| 373 | if (device) { | ||
| 374 | idevice_free(device); | ||
| 375 | } | 350 | } |
| 376 | 351 | ||
| 377 | return result; | 352 | return result; |
