summaryrefslogtreecommitdiffstats
path: root/src/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.c')
-rw-r--r--src/client.c172
1 files changed, 113 insertions, 59 deletions
diff --git a/src/client.c b/src/client.c
index 85d0c8b..dbbdd5f 100644
--- a/src/client.c
+++ b/src/client.c
@@ -31,13 +31,15 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/un.h>
#include <arpa/inet.h>
-#include <pthread.h>
#include <fcntl.h>
#include <plist/plist.h>
+#include <libimobiledevice-glue/collection.h>
+#include <libimobiledevice-glue/thread.h>
#include "log.h"
#include "usb.h"
@@ -75,9 +77,30 @@ struct mux_client {
};
static struct collection client_list;
-pthread_mutex_t client_list_mutex;
+mutex_t client_list_mutex;
static uint32_t client_number = 0;
+#ifdef SO_PEERCRED
+static char* _get_process_name_by_pid(const int pid)
+{
+ char* name = (char*)calloc(1024, sizeof(char));
+ if(name) {
+ sprintf(name, "/proc/%d/cmdline", pid);
+ FILE* f = fopen(name, "r");
+ if(f) {
+ size_t size;
+ size = fread(name, sizeof(char), 1024, f);
+ if(size > 0) {
+ if('\n' == name[size-1])
+ name[size-1]='\0';
+ }
+ fclose(f);
+ }
+ }
+ return name;
+}
+#endif
+
/**
* Receive raw data from the client socket.
*
@@ -203,32 +226,64 @@ int client_accept(int listenfd)
client->events = POLLIN;
client->info = NULL;
- pthread_mutex_lock(&client_list_mutex);
+ mutex_lock(&client_list_mutex);
client->number = client_number++;
collection_add(&client_list, client);
- pthread_mutex_unlock(&client_list_mutex);
+ mutex_unlock(&client_list_mutex);
#ifdef SO_PEERCRED
if (log_level >= LL_INFO) {
struct ucred cr;
len = sizeof(struct ucred);
- getsockopt(cfd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
+ getsockopt(client->fd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
if (getpid() == cr.pid) {
- usbmuxd_log(LL_INFO, "New client on fd %d (self)", client->fd);
+ usbmuxd_log(LL_INFO, "Client %d accepted: %s[%d]", client->fd, PACKAGE_NAME, cr.pid);
} else {
- usbmuxd_log(LL_INFO, "New client on fd %d (pid %d)", client->fd, cr.pid);
+ char* process_name = _get_process_name_by_pid(cr.pid);
+ usbmuxd_log(LL_INFO, "Client %d accepted: %s[%d]", client->fd, process_name, cr.pid);
+ free(process_name);
}
}
#else
- usbmuxd_log(LL_INFO, "New client on fd %d", client->fd);
+ usbmuxd_log(LL_INFO, "Client %d accepted", client->fd);
#endif
return client->fd;
}
void client_close(struct mux_client *client)
{
- usbmuxd_log(LL_INFO, "Disconnecting client fd %d", client->fd);
+ int found = 0;
+ mutex_lock(&client_list_mutex);
+ FOREACH(struct mux_client *lc, &client_list) {
+ if (client == lc) {
+ found = 1;
+ break;
+ }
+ } ENDFOREACH
+ if (!found) {
+ // in case we get called again but client was already freed
+ usbmuxd_log(LL_DEBUG, "%s: ignoring for non-existing client %p", __func__, client);
+ mutex_unlock(&client_list_mutex);
+ return;
+ }
+#ifdef SO_PEERCRED
+ if (log_level >= LL_INFO) {
+ struct ucred cr;
+ socklen_t len = sizeof(struct ucred);
+ getsockopt(client->fd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
+
+ if (getpid() == cr.pid) {
+ usbmuxd_log(LL_INFO, "Client %d is going to be disconnected: %s[%d]", client->fd, PACKAGE_NAME, cr.pid);
+ } else {
+ char* process_name = _get_process_name_by_pid(cr.pid);
+ usbmuxd_log(LL_INFO, "Client %d is going to be disconnected: %s[%d]", client->fd, process_name, cr.pid);
+ free(process_name);
+ }
+ }
+#else
+ usbmuxd_log(LL_INFO, "Client %d is going to be disconnected", client->fd);
+#endif
if(client->state == CLIENT_CONNECTING1 || client->state == CLIENT_CONNECTING2) {
usbmuxd_log(LL_INFO, "Client died mid-connect, aborting device %d connection", client->connect_device);
client->state = CLIENT_DEAD;
@@ -239,29 +294,28 @@ void client_close(struct mux_client *client)
free(client->ib_buf);
plist_free(client->info);
- pthread_mutex_lock(&client_list_mutex);
collection_remove(&client_list, client);
- pthread_mutex_unlock(&client_list_mutex);
+ mutex_unlock(&client_list_mutex);
free(client);
}
void client_get_fds(struct fdlist *list)
{
- pthread_mutex_lock(&client_list_mutex);
+ mutex_lock(&client_list_mutex);
FOREACH(struct mux_client *client, &client_list) {
fdlist_add(list, FD_CLIENT, client->fd, client->events);
} ENDFOREACH
- pthread_mutex_unlock(&client_list_mutex);
+ mutex_unlock(&client_list_mutex);
}
-static int send_pkt(struct mux_client *client, uint32_t tag, enum usbmuxd_msgtype msg, void *payload, int payload_length)
+static int output_buffer_add_message(struct mux_client *client, uint32_t tag, enum usbmuxd_msgtype msg, void *payload, int payload_length)
{
struct usbmuxd_header hdr;
hdr.version = client->proto_version;
hdr.length = sizeof(hdr) + payload_length;
hdr.message = msg;
hdr.tag = tag;
- usbmuxd_log(LL_DEBUG, "send_pkt fd %d tag %d msg %d payload_length %d", client->fd, tag, msg, payload_length);
+ usbmuxd_log(LL_DEBUG, "Client %d output buffer got tag %d msg %d payload_length %d", client->fd, tag, msg, payload_length);
uint32_t available = client->ob_capacity - client->ob_size;
/* the output buffer _should_ be large enough, but just in case */
@@ -285,14 +339,14 @@ static int send_pkt(struct mux_client *client, uint32_t tag, enum usbmuxd_msgtyp
return hdr.length;
}
-static int send_plist_pkt(struct mux_client *client, uint32_t tag, plist_t plist)
+static int send_plist(struct mux_client *client, uint32_t tag, plist_t plist)
{
int res = -1;
char *xml = NULL;
uint32_t xmlsize = 0;
plist_to_xml(plist, &xml, &xmlsize);
if (xml) {
- res = send_pkt(client, tag, MESSAGE_PLIST, xml, xmlsize);
+ res = output_buffer_add_message(client, tag, MESSAGE_PLIST, xml, xmlsize);
free(xml);
} else {
usbmuxd_log(LL_ERROR, "%s: Could not convert plist to xml", __func__);
@@ -308,11 +362,11 @@ static int send_result(struct mux_client *client, uint32_t tag, uint32_t result)
plist_t dict = plist_new_dict();
plist_dict_set_item(dict, "MessageType", plist_new_string("Result"));
plist_dict_set_item(dict, "Number", plist_new_uint(result));
- res = send_plist_pkt(client, tag, dict);
+ res = send_plist(client, tag, dict);
plist_free(dict);
} else {
/* binary packet */
- res = send_pkt(client, tag, MESSAGE_RESULT, &result, sizeof(uint32_t));
+ res = output_buffer_add_message(client, tag, MESSAGE_RESULT, &result, sizeof(uint32_t));
}
return res;
}
@@ -378,7 +432,7 @@ static int send_device_list(struct mux_client *client, uint32_t tag)
free(devs);
plist_dict_set_item(dict, "DeviceList", devices);
- res = send_plist_pkt(client, tag, dict);
+ res = send_plist(client, tag, dict);
plist_free(dict);
return res;
}
@@ -390,7 +444,7 @@ static int send_listener_list(struct mux_client *client, uint32_t tag)
plist_t dict = plist_new_dict();
plist_t listeners = plist_new_array();
- pthread_mutex_lock(&client_list_mutex);
+ mutex_lock(&client_list_mutex);
FOREACH(struct mux_client *lc, &client_list) {
if (lc->state == CLIENT_LISTEN) {
plist_t n = NULL;
@@ -437,10 +491,10 @@ static int send_listener_list(struct mux_client *client, uint32_t tag)
plist_array_append_item(listeners, l);
}
} ENDFOREACH
- pthread_mutex_unlock(&client_list_mutex);
+ mutex_unlock(&client_list_mutex);
plist_dict_set_item(dict, "ListenerList", listeners);
- res = send_plist_pkt(client, tag, dict);
+ res = send_plist(client, tag, dict);
plist_free(dict);
return res;
@@ -456,7 +510,7 @@ static int send_system_buid(struct mux_client *client, uint32_t tag)
plist_t dict = plist_new_dict();
plist_dict_set_item(dict, "BUID", plist_new_string(buid));
free(buid);
- res = send_plist_pkt(client, tag, dict);
+ res = send_plist(client, tag, dict);
plist_free(dict);
return res;
}
@@ -472,12 +526,12 @@ static int send_pair_record(struct mux_client *client, uint32_t tag, const char*
}
config_get_device_record(record_id, &record_data, &record_size);
-
+
if (record_data) {
plist_t dict = plist_new_dict();
plist_dict_set_item(dict, "PairRecordData", plist_new_data(record_data, record_size));
free(record_data);
- res = send_plist_pkt(client, tag, dict);
+ res = send_plist(client, tag, dict);
plist_free(dict);
} else {
res = send_result(client, tag, ENOENT);
@@ -485,13 +539,13 @@ static int send_pair_record(struct mux_client *client, uint32_t tag, const char*
return res;
}
-static int notify_device_add(struct mux_client *client, struct device_info *dev)
+static int send_device_add(struct mux_client *client, struct device_info *dev)
{
int res = -1;
if (client->proto_version == 1) {
/* XML plist packet */
plist_t dict = create_device_attached_plist(dev);
- res = send_plist_pkt(client, 0, dict);
+ res = send_plist(client, 0, dict);
plist_free(dict);
} else {
/* binary packet */
@@ -502,12 +556,12 @@ static int notify_device_add(struct mux_client *client, struct device_info *dev)
dmsg.serial_number[255] = 0;
dmsg.location = dev->location;
dmsg.product_id = dev->pid;
- res = send_pkt(client, 0, MESSAGE_DEVICE_ADD, &dmsg, sizeof(dmsg));
+ res = output_buffer_add_message(client, 0, MESSAGE_DEVICE_ADD, &dmsg, sizeof(dmsg));
}
return res;
}
-static int notify_device_remove(struct mux_client *client, uint32_t device_id)
+static int send_device_remove(struct mux_client *client, uint32_t device_id)
{
int res = -1;
if (client->proto_version == 1) {
@@ -515,16 +569,16 @@ static int notify_device_remove(struct mux_client *client, uint32_t device_id)
plist_t dict = plist_new_dict();
plist_dict_set_item(dict, "MessageType", plist_new_string("Detached"));
plist_dict_set_item(dict, "DeviceID", plist_new_uint(device_id));
- res = send_plist_pkt(client, 0, dict);
+ res = send_plist(client, 0, dict);
plist_free(dict);
} else {
/* binary packet */
- res = send_pkt(client, 0, MESSAGE_DEVICE_REMOVE, &device_id, sizeof(uint32_t));
+ res = output_buffer_add_message(client, 0, MESSAGE_DEVICE_REMOVE, &device_id, sizeof(uint32_t));
}
return res;
}
-static int notify_device_paired(struct mux_client *client, uint32_t device_id)
+static int send_device_paired(struct mux_client *client, uint32_t device_id)
{
int res = -1;
if (client->proto_version == 1) {
@@ -532,12 +586,12 @@ static int notify_device_paired(struct mux_client *client, uint32_t device_id)
plist_t dict = plist_new_dict();
plist_dict_set_item(dict, "MessageType", plist_new_string("Paired"));
plist_dict_set_item(dict, "DeviceID", plist_new_uint(device_id));
- res = send_plist_pkt(client, 0, dict);
+ res = send_plist(client, 0, dict);
plist_free(dict);
}
else {
/* binary packet */
- res = send_pkt(client, 0, MESSAGE_DEVICE_PAIRED, &device_id, sizeof(uint32_t));
+ res = output_buffer_add_message(client, 0, MESSAGE_DEVICE_PAIRED, &device_id, sizeof(uint32_t));
}
return res;
}
@@ -553,7 +607,7 @@ static int start_listen(struct mux_client *client)
count = device_get_list(0, &devs);
dev = devs;
for(i=0; devs && i < count; i++) {
- if(notify_device_add(client, dev++) < 0) {
+ if(send_device_add(client, dev++) < 0) {
free(devs);
return -1;
}
@@ -604,13 +658,13 @@ static void update_client_info(struct mux_client *client, plist_t dict)
client->info = info;
}
-static int client_command(struct mux_client *client, struct usbmuxd_header *hdr)
+static int handle_command(struct mux_client *client, struct usbmuxd_header *hdr)
{
int res;
- usbmuxd_log(LL_DEBUG, "Client command in fd %d len %d ver %d msg %d tag %d", client->fd, hdr->length, hdr->version, hdr->message, hdr->tag);
+ usbmuxd_log(LL_DEBUG, "Client %d command len %d ver %d msg %d tag %d", client->fd, hdr->length, hdr->version, hdr->message, hdr->tag);
if(client->state != CLIENT_COMMAND) {
- usbmuxd_log(LL_ERROR, "Client %d command received in the wrong state", client->fd);
+ usbmuxd_log(LL_ERROR, "Client %d command received in the wrong state, got %d but want %d", client->fd, client->state, CLIENT_COMMAND);
if(send_result(client, hdr->tag, RESULT_BADCOMMAND) < 0)
return -1;
client_close(client);
@@ -691,7 +745,7 @@ static int client_command(struct mux_client *client, struct usbmuxd_header *hdr)
portnum = (uint16_t)val;
plist_free(dict);
- usbmuxd_log(LL_DEBUG, "Client %d connection request to device %d port %d", client->fd, device_id, ntohs(portnum));
+ usbmuxd_log(LL_DEBUG, "Client %d requesting connection to device %d port %d", client->fd, device_id, ntohs(portnum));
res = device_start_connect(device_id, ntohs(portnum), client);
if(res < 0) {
if (send_result(client, hdr->tag, -res) < 0)
@@ -839,7 +893,7 @@ static int client_command(struct mux_client *client, struct usbmuxd_header *hdr)
return -1;
}
-static void process_send(struct mux_client *client)
+static void output_buffer_process(struct mux_client *client)
{
int res;
if(!client->ob_size) {
@@ -849,7 +903,7 @@ static void process_send(struct mux_client *client)
}
res = send(client->fd, client->ob_buf, client->ob_size, 0);
if(res <= 0) {
- usbmuxd_log(LL_ERROR, "Send to client fd %d failed: %d %s", client->fd, res, strerror(errno));
+ usbmuxd_log(LL_ERROR, "Sending to client fd %d failed: %d %s", client->fd, res, strerror(errno));
client_close(client);
return;
}
@@ -869,7 +923,7 @@ static void process_send(struct mux_client *client)
memmove(client->ob_buf, client->ob_buf + res, client->ob_size);
}
}
-static void process_recv(struct mux_client *client)
+static void input_buffer_process(struct mux_client *client)
{
int res;
int did_read = 0;
@@ -916,21 +970,21 @@ static void process_recv(struct mux_client *client)
if(client->ib_size < hdr->length)
return;
}
- client_command(client, hdr);
+ handle_command(client, hdr);
client->ib_size = 0;
}
void client_process(int fd, short events)
{
struct mux_client *client = NULL;
- pthread_mutex_lock(&client_list_mutex);
+ mutex_lock(&client_list_mutex);
FOREACH(struct mux_client *lc, &client_list) {
if(lc->fd == fd) {
client = lc;
break;
}
} ENDFOREACH
- pthread_mutex_unlock(&client_list_mutex);
+ mutex_unlock(&client_list_mutex);
if(!client) {
usbmuxd_log(LL_INFO, "client_process: fd %d not found in client list", fd);
@@ -942,9 +996,9 @@ void client_process(int fd, short events)
device_client_process(client->connect_device, client, events);
} else {
if(events & POLLIN) {
- process_recv(client);
+ input_buffer_process(client);
} else if(events & POLLOUT) { //not both in case client died as part of process_recv
- process_send(client);
+ output_buffer_process(client);
}
}
@@ -952,45 +1006,45 @@ void client_process(int fd, short events)
void client_device_add(struct device_info *dev)
{
- pthread_mutex_lock(&client_list_mutex);
+ mutex_lock(&client_list_mutex);
usbmuxd_log(LL_DEBUG, "client_device_add: id %d, location 0x%x, serial %s", dev->id, dev->location, dev->serial);
device_set_visible(dev->id);
FOREACH(struct mux_client *client, &client_list) {
if(client->state == CLIENT_LISTEN)
- notify_device_add(client, dev);
+ send_device_add(client, dev);
} ENDFOREACH
- pthread_mutex_unlock(&client_list_mutex);
+ mutex_unlock(&client_list_mutex);
}
void client_device_remove(int device_id)
{
- pthread_mutex_lock(&client_list_mutex);
+ mutex_lock(&client_list_mutex);
uint32_t id = device_id;
usbmuxd_log(LL_DEBUG, "client_device_remove: id %d", device_id);
FOREACH(struct mux_client *client, &client_list) {
if(client->state == CLIENT_LISTEN)
- notify_device_remove(client, id);
+ send_device_remove(client, id);
} ENDFOREACH
- pthread_mutex_unlock(&client_list_mutex);
+ mutex_unlock(&client_list_mutex);
}
void client_device_paired(int device_id)
{
- pthread_mutex_lock(&client_list_mutex);
+ mutex_lock(&client_list_mutex);
uint32_t id = device_id;
usbmuxd_log(LL_DEBUG, "client_device_paired: id %d", device_id);
FOREACH(struct mux_client *client, &client_list) {
if (client->state == CLIENT_LISTEN)
- notify_device_paired(client, id);
+ send_device_paired(client, id);
} ENDFOREACH
- pthread_mutex_unlock(&client_list_mutex);
+ mutex_unlock(&client_list_mutex);
}
void client_init(void)
{
usbmuxd_log(LL_DEBUG, "client_init");
collection_init(&client_list);
- pthread_mutex_init(&client_list_mutex, NULL);
+ mutex_init(&client_list_mutex);
}
void client_shutdown(void)
@@ -999,6 +1053,6 @@ void client_shutdown(void)
FOREACH(struct mux_client *client, &client_list) {
client_close(client);
} ENDFOREACH
- pthread_mutex_destroy(&client_list_mutex);
+ mutex_destroy(&client_list_mutex);
collection_free(&client_list);
}