From 2c83cae88c50217f0fbbff5c3d2eab5f252f164e Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Mon, 18 May 2020 03:01:28 +0200 Subject: Use direct socket connection for network devices Instead of relaying data via usbmuxd this change will have it connect directly to the device via network after retrieving its address from usbmuxd --- src/idevice.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 7 deletions(-) diff --git a/src/idevice.c b/src/idevice.c index 0a62907..418ee86 100644 --- a/src/idevice.c +++ b/src/idevice.c @@ -421,7 +421,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connect(idevice_t device, uint16_t return IDEVICE_E_INVALID_ARG; } - if (device->conn_type == CONNECTION_USBMUXD || device->conn_type == CONNECTION_NETWORK) { + if (device->conn_type == CONNECTION_USBMUXD) { int sfd = usbmuxd_connect(device->mux_id, port); if (sfd < 0) { debug_info("ERROR: Connecting to usbmuxd failed: %d (%s)", sfd, strerror(-sfd)); @@ -434,6 +434,45 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connect(idevice_t device, uint16_t new_connection->device = device; *connection = new_connection; return IDEVICE_E_SUCCESS; + } else if (device->conn_type == CONNECTION_NETWORK) { + unsigned char saddr_[32]; + memset(saddr_, '\0', sizeof(saddr_)); + struct sockaddr* saddr = (struct sockaddr*)&saddr_[0]; + if (((char*)device->conn_data)[1] == 0x02) { // AF_INET + saddr->sa_family = AF_INET; + memcpy(&saddr->sa_data[0], (char*)device->conn_data+2, 14); + } + else if (((char*)device->conn_data)[1] == 0x1E) { //AF_INET6 (bsd) +#ifdef AF_INET6 + saddr->sa_family = AF_INET6; + memcpy(&saddr->sa_data[0], (char*)device->conn_data+2, 26); +#else + debug_info("ERROR: Got an IPv6 address but this system doesn't support IPv6"); + return IDEVICE_E_UNKNOWN_ERROR; +#endif + } + else { + debug_info("Unsupported address family 0x%02x", ((char*)device->conn_data)[1]); + return IDEVICE_E_UNKNOWN_ERROR; + } + char addrtxt[48]; + addrtxt[0] = '\0'; + if (!socket_addr_to_string(saddr, addrtxt, sizeof(addrtxt))) { + debug_info("Failed to convert network address: %d (%s)", errno, strerror(errno)); + } + debug_info("Connecting to %s port %d...", addrtxt, port); + int sfd = socket_connect_addr(saddr, port); + if (sfd < 0) { + debug_info("ERROR: Connecting to network device failed: %d (%s)", errno, strerror(errno)); + return IDEVICE_E_NO_DEVICE; + } + idevice_connection_t new_connection = (idevice_connection_t)malloc(sizeof(struct idevice_connection_private)); + new_connection->type = CONNECTION_NETWORK; + new_connection->data = (void*)(long)sfd; + new_connection->ssl_data = NULL; + new_connection->device = device; + *connection = new_connection; + return IDEVICE_E_SUCCESS; } else { debug_info("Unknown connection type %d", device->conn_type); } @@ -451,10 +490,14 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_disconnect(idevice_connection_t con idevice_connection_disable_ssl(connection); } idevice_error_t result = IDEVICE_E_UNKNOWN_ERROR; - if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { + if (connection->type == CONNECTION_USBMUXD) { usbmuxd_disconnect((int)(long)connection->data); connection->data = NULL; result = IDEVICE_E_SUCCESS; + } else if (connection->type == CONNECTION_NETWORK) { + socket_close((int)(long)connection->data); + connection->data = NULL; + result = IDEVICE_E_SUCCESS; } else { debug_info("Unknown connection type %d", connection->type); } @@ -474,13 +517,21 @@ static idevice_error_t internal_connection_send(idevice_connection_t connection, return IDEVICE_E_INVALID_ARG; } - if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { + if (connection->type == CONNECTION_USBMUXD) { int res = usbmuxd_send((int)(long)connection->data, data, len, sent_bytes); if (res < 0) { debug_info("ERROR: usbmuxd_send returned %d (%s)", res, strerror(-res)); return IDEVICE_E_UNKNOWN_ERROR; } return IDEVICE_E_SUCCESS; + } else if (connection->type == CONNECTION_NETWORK) { + int s = socket_send((int)(long)connection->data, (void*)data, len); + if (s < 0) { + *sent_bytes = 0; + return IDEVICE_E_UNKNOWN_ERROR; + } + *sent_bytes = s; + return IDEVICE_E_SUCCESS; } else { debug_info("Unknown connection type %d", connection->type); } @@ -545,7 +596,7 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t return IDEVICE_E_INVALID_ARG; } - if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { + if (connection->type == CONNECTION_USBMUXD) { int conn_error = usbmuxd_recv_timeout((int)(long)connection->data, data, len, recv_bytes, timeout); idevice_error_t error = socket_recv_to_idevice_error(conn_error, len, *recv_bytes); @@ -554,6 +605,14 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t } return error; + } else if (connection->type == CONNECTION_NETWORK) { + int res = socket_receive_timeout((int)(long)connection->data, data, len, 0, timeout); + if (res < 0) { + debug_info("ERROR: socket_receive_timeout failed: %d (%s)", res, strerror(-res)); + return (res == -EAGAIN ? IDEVICE_E_NOT_ENOUGH_DATA : IDEVICE_E_UNKNOWN_ERROR); + } + *recv_bytes = (uint32_t)res; + return IDEVICE_E_SUCCESS; } else { debug_info("Unknown connection type %d", connection->type); } @@ -630,13 +689,20 @@ static idevice_error_t internal_connection_receive(idevice_connection_t connecti return IDEVICE_E_INVALID_ARG; } - if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { + if (connection->type == CONNECTION_USBMUXD) { int res = usbmuxd_recv((int)(long)connection->data, data, len, recv_bytes); if (res < 0) { debug_info("ERROR: usbmuxd_recv returned %d (%s)", res, strerror(-res)); return IDEVICE_E_UNKNOWN_ERROR; } - + return IDEVICE_E_SUCCESS; + } else if (connection->type == CONNECTION_NETWORK) { + int res = socket_receive((int)(long)connection->data, data, len); + if (res < 0) { + debug_info("ERROR: socket_receive returned %d (%s)", res, strerror(-res)); + return IDEVICE_E_UNKNOWN_ERROR; + } + *recv_bytes = (uint32_t)res; return IDEVICE_E_SUCCESS; } else { debug_info("Unknown connection type %d", connection->type); @@ -674,7 +740,10 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_get_fd(idevice_connectio } idevice_error_t result = IDEVICE_E_UNKNOWN_ERROR; - if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { + if (connection->type == CONNECTION_USBMUXD) { + *fd = (int)(long)connection->data; + result = IDEVICE_E_SUCCESS; + } else if (connection->type == CONNECTION_NETWORK) { *fd = (int)(long)connection->data; result = IDEVICE_E_SUCCESS; } else { -- cgit v1.1-32-gdbae