diff options
| -rw-r--r-- | iphone.c | 53 |
1 files changed, 33 insertions, 20 deletions
| @@ -99,6 +99,8 @@ struct iphone_umux_client_int { | |||
| 99 | // this will then be set to the error that caused the broken stream. | 99 | // this will then be set to the error that caused the broken stream. |
| 100 | // no further operations other than free_client will be allowed. | 100 | // no further operations other than free_client will be allowed. |
| 101 | iphone_error_t error; | 101 | iphone_error_t error; |
| 102 | |||
| 103 | int cleanup; | ||
| 102 | }; | 104 | }; |
| 103 | 105 | ||
| 104 | 106 | ||
| @@ -728,6 +730,7 @@ iphone_error_t iphone_mux_new_client(iphone_device_t device, uint16_t src_port, | |||
| 728 | new_connection->wr_window = 0; | 730 | new_connection->wr_window = 0; |
| 729 | add_connection(new_connection); | 731 | add_connection(new_connection); |
| 730 | new_connection->error = IPHONE_E_SUCCESS; | 732 | new_connection->error = IPHONE_E_SUCCESS; |
| 733 | new_connection->cleanup = 0; | ||
| 731 | hton_header(new_connection->header); | 734 | hton_header(new_connection->header); |
| 732 | log_debug_msg("%s: send_to_phone (%d --> %d)\n", __func__, ntohs(new_connection->header->sport), ntohs(new_connection->header->dport)); | 735 | log_debug_msg("%s: send_to_phone (%d --> %d)\n", __func__, ntohs(new_connection->header->sport), ntohs(new_connection->header->dport)); |
| 733 | if (send_to_phone(device, (char *) new_connection->header, sizeof(usbmux_tcp_header)) >= 0) { | 736 | if (send_to_phone(device, (char *) new_connection->header, sizeof(usbmux_tcp_header)) >= 0) { |
| @@ -754,36 +757,33 @@ iphone_error_t iphone_mux_free_client(iphone_umux_client_t client) | |||
| 754 | if (!client || !client->phone) | 757 | if (!client || !client->phone) |
| 755 | return IPHONE_E_INVALID_ARG; | 758 | return IPHONE_E_INVALID_ARG; |
| 756 | 759 | ||
| 757 | pthread_mutex_lock(&client->mutex); | 760 | iphone_error_t result = IPHONE_E_SUCCESS; |
| 761 | pthread_mutex_lock(&client->mutex); | ||
| 758 | client->header->tcp_flags = TCP_FIN; | 762 | client->header->tcp_flags = TCP_FIN; |
| 759 | client->header->length = 0x1C; | 763 | client->header->length = 0x1C; |
| 760 | client->header->window = 0; | 764 | client->header->window = 0; |
| 761 | client->header->length16 = 0x1C; | 765 | client->header->length16 = 0x1C; |
| 762 | hton_header(client->header); | 766 | hton_header(client->header); |
| 763 | int bytes = 0; | ||
| 764 | 767 | ||
| 765 | bytes = usb_bulk_write(client->phone->device, BULKOUT, (char *) client->header, sizeof(usbmux_tcp_header), 800); | 768 | if (send_to_phone(client->phone, (char*)client->header, sizeof(usbmux_tcp_header)) < 0) { |
| 766 | if (bytes < 0) | 769 | log_debug_msg("%s: error sending TCP_FIN\n", __func__); |
| 767 | log_debug_msg("iphone_mux_free_client(): when writing, libusb gave me the error: %s\n", usb_strerror()); | 770 | result = IPHONE_E_UNKNOWN_ERROR; |
| 771 | } | ||
| 768 | 772 | ||
| 769 | bytes = usb_bulk_read(client->phone->device, BULKIN, (char *) client->header, sizeof(usbmux_tcp_header), 800); | 773 | client->cleanup = 1; |
| 770 | if (bytes < 0) | ||
| 771 | log_debug_msg("get_iPhone(): when reading, libusb gave me the error: %s\n", usb_strerror()); | ||
| 772 | |||
| 773 | pthread_mutex_unlock(&client->mutex); | ||
| 774 | // make sure we don't have any last-minute laggards waiting on this. | ||
| 775 | // I put it after the mutex unlock because we have cases where the | ||
| 776 | // conditional wait is dependent on re-grabbing that mutex. | ||
| 777 | pthread_cond_broadcast(&client->wait); | ||
| 778 | pthread_cond_destroy(&client->wait); | ||
| 779 | pthread_cond_broadcast(&client->wr_wait); | ||
| 780 | pthread_cond_destroy(&client->wr_wait); | ||
| 781 | 774 | ||
| 782 | delete_connection(client); | 775 | // make sure we don't have any last-minute laggards waiting on this. |
| 776 | // I put it after the mutex unlock because we have cases where the | ||
| 777 | // conditional wait is dependent on re-grabbing that mutex. | ||
| 778 | pthread_cond_broadcast(&client->wait); | ||
| 779 | pthread_cond_destroy(&client->wait); | ||
| 780 | pthread_cond_broadcast(&client->wr_wait); | ||
| 781 | pthread_cond_destroy(&client->wr_wait); | ||
| 783 | 782 | ||
| 784 | return IPHONE_E_SUCCESS; | 783 | pthread_mutex_unlock(&client->mutex); |
| 785 | } | ||
| 786 | 784 | ||
| 785 | return result; | ||
| 786 | } | ||
| 787 | 787 | ||
| 788 | /** Sends the given data over the selected connection. | 788 | /** Sends the given data over the selected connection. |
| 789 | * | 789 | * |
| @@ -1113,6 +1113,19 @@ int iphone_mux_pullbulk(iphone_device_t phone) | |||
| 1113 | // stuff the data | 1113 | // stuff the data |
| 1114 | log_debug_msg("%s: found client, calling append_receive_buffer\n", __func__); | 1114 | log_debug_msg("%s: found client, calling append_receive_buffer\n", __func__); |
| 1115 | append_receive_buffer(client, cursor); | 1115 | append_receive_buffer(client, cursor); |
| 1116 | |||
| 1117 | // perhaps this is too general, == IPHONE_E_ECONNRESET | ||
| 1118 | // might be a better check here | ||
| 1119 | if (client->error != IPHONE_E SUCCESS) { | ||
| 1120 | pthread_mutex_lock(&client->mutex); | ||
| 1121 | if (client->cleanup) { | ||
| 1122 | pthread_mutex_unlock(&client->mutex); | ||
| 1123 | log_debug_msg("freeing up connection (%d->%d)\n", ntohs(client->header->sport), ntohs(client->header->dport)); | ||
| 1124 | delete_connection(client); | ||
| 1125 | } else { | ||
| 1126 | pthread_mutex_unlock(&client->mutex); | ||
| 1127 | } | ||
| 1128 | } | ||
| 1116 | } | 1129 | } |
| 1117 | 1130 | ||
| 1118 | // move the cursor and account for the consumption | 1131 | // move the cursor and account for the consumption |
