[Spice-commits] 2 commits - server/inputs_channel.c server/main_channel.c server/red_channel.c server/red_tunnel_worker.c server/red_worker.c server/smartcard.c server/snd_worker.c

Yonit Halperin yhalperi at kemper.freedesktop.org
Sun May 20 23:08:47 PDT 2012


 server/inputs_channel.c    |    3 ++
 server/main_channel.c      |    2 -
 server/red_channel.c       |   50 +++++++++++++++++++++++++++++++++++++++++----
 server/red_tunnel_worker.c |    4 ++-
 server/red_worker.c        |    3 ++
 server/smartcard.c         |    3 ++
 server/snd_worker.c        |    3 ++
 7 files changed, 62 insertions(+), 6 deletions(-)

New commits:
commit 038ae54b1c4c43a63d346bdfe2db52b48f20a22e
Author: Yonit Halperin <yhalperi at redhat.com>
Date:   Sun May 20 13:27:31 2012 +0300

    server: handle red_channel_client_create returning NULL

diff --git a/server/inputs_channel.c b/server/inputs_channel.c
index ad247f4..e14e995 100644
--- a/server/inputs_channel.c
+++ b/server/inputs_channel.c
@@ -502,6 +502,9 @@ static void inputs_connect(RedChannel *channel, RedClient *client,
                                                           stream,
                                                           num_common_caps, common_caps,
                                                           num_caps, caps);
+    if (!icc) {
+        return;
+    }
     icc->motion_count = 0;
     inputs_pipe_add_init(&icc->base);
 }
diff --git a/server/main_channel.c b/server/main_channel.c
index 713f121..ace24ff 100644
--- a/server/main_channel.c
+++ b/server/main_channel.c
@@ -998,7 +998,7 @@ static MainChannelClient *main_channel_client_create(MainChannel *main_chan, Red
                              red_channel_client_create(sizeof(MainChannelClient), &main_chan->base,
                                                        client, stream, num_common_caps,
                                                        common_caps, num_caps, caps);
-
+    spice_assert(mcc != NULL);
     mcc->connection_id = connection_id;
     mcc->bitrate_per_sec = ~0;
 #ifdef RED_STATISTICS
diff --git a/server/red_tunnel_worker.c b/server/red_tunnel_worker.c
index 384c36d..12f3106 100644
--- a/server/red_tunnel_worker.c
+++ b/server/red_tunnel_worker.c
@@ -3452,7 +3452,9 @@ static void handle_tunnel_channel_link(RedChannel *channel, RedClient *client,
     tcc = (TunnelChannelClient*)red_channel_client_create(sizeof(TunnelChannelClient),
                                                           channel, client, stream,
                                                           0, NULL, 0, NULL);
-
+    if (!tcc) {
+        return;
+    }
     tcc->worker = worker;
     tcc->worker->channel_client = tcc;
     net_slirp_set_net_interface(&worker->tunnel_interface.base);
diff --git a/server/red_worker.c b/server/red_worker.c
index 3a0bdf4..9e5624b 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -9773,6 +9773,9 @@ static CommonChannelClient *common_channel_client_create(int size,
     RedChannelClient *rcc =
         red_channel_client_create(size, &common->base, client, stream,
                                   num_common_caps, common_caps, num_caps, caps);
+    if (!rcc) {
+        return NULL;
+    }
     CommonChannelClient *common_cc = (CommonChannelClient*)rcc;
     common_cc->worker = common->worker;
     common_cc->id = common->worker->id;
diff --git a/server/smartcard.c b/server/smartcard.c
index eb2823a..8ded142 100644
--- a/server/smartcard.c
+++ b/server/smartcard.c
@@ -500,6 +500,9 @@ static void smartcard_connect(RedChannel *channel, RedClient *client,
     rcc = red_channel_client_create(sizeof(RedChannelClient), channel, client, stream,
                                     num_common_caps, common_caps,
                                     num_caps, caps);
+    if (!rcc) {
+        return;
+    }
     red_channel_client_ack_zero_messages_window(rcc);
 }
 
diff --git a/server/snd_worker.c b/server/snd_worker.c
index caffe67..3599c6f 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -975,6 +975,9 @@ static SndChannel *__new_channel(SndWorker *worker, int size, uint32_t channel_i
                                                               client,
                                                               num_common_caps, common_caps,
                                                               num_caps, caps);
+    if (!channel->channel_client) {
+        goto error2;
+    }
     return channel;
 
 error2:
commit 1b9162b5cfe4043df851e8ecaa503b8261ba5868
Author: Yonit Halperin <yhalperi at redhat.com>
Date:   Sun May 20 13:23:19 2012 +0300

    server/red_channel: prevent creating more than one channel client with the same type+id

diff --git a/server/red_channel.c b/server/red_channel.c
index 4858bb5..a7ef934 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -40,6 +40,7 @@
 static void red_channel_client_event(int fd, int event, void *data);
 static void red_client_add_channel(RedClient *client, RedChannelClient *rcc);
 static void red_client_remove_channel(RedChannelClient *rcc);
+static RedChannelClient *red_client_get_channel(RedClient *client, int type, int id);
 static void red_channel_client_restore_main_sender(RedChannelClient *rcc);
 
 static uint32_t full_header_get_msg_size(SpiceDataHeaderOpaque *header)
@@ -514,13 +515,27 @@ int red_channel_client_test_remote_cap(RedChannelClient *rcc, uint32_t cap)
                           cap);
 }
 
+static int red_channle_client_pre_create_validate(RedChannel *channel, RedClient  *client)
+{
+    if (red_client_get_channel(client, channel->type, channel->id)) {
+        spice_printerr("Error client %p: duplicate channel type %d id %d",
+                       client, channel->type, channel->id);
+        return FALSE;
+    }
+    return TRUE;
+}
+
 RedChannelClient *red_channel_client_create(int size, RedChannel *channel, RedClient  *client,
                                             RedsStream *stream,
                                             int num_common_caps, uint32_t *common_caps,
                                             int num_caps, uint32_t *caps)
 {
-    RedChannelClient *rcc;
+    RedChannelClient *rcc = NULL;
 
+    pthread_mutex_lock(&client->lock);
+    if (!red_channle_client_pre_create_validate(channel, client)) {
+        goto error;
+    }
     spice_assert(stream && channel && size >= sizeof(RedChannelClient));
     rcc = spice_malloc0(size);
     rcc->stream = stream;
@@ -570,10 +585,12 @@ RedChannelClient *red_channel_client_create(int size, RedChannel *channel, RedCl
     rcc->id = channel->clients_num;
     red_channel_add_client(channel, rcc);
     red_client_add_channel(client, rcc);
+    pthread_mutex_unlock(&client->lock);
     return rcc;
 error:
     free(rcc);
     reds_stream_free(stream);
+    pthread_mutex_unlock(&client->lock);
     return NULL;
 }
 
@@ -1220,9 +1237,14 @@ RedChannelClient *red_channel_client_create_dummy(int size,
                                                   int num_common_caps, uint32_t *common_caps,
                                                   int num_caps, uint32_t *caps)
 {
-    RedChannelClient *rcc;
+    RedChannelClient *rcc = NULL;
 
     spice_assert(size >= sizeof(RedChannelClient));
+
+    pthread_mutex_lock(&client->lock);
+    if (!red_channle_client_pre_create_validate(channel, client)) {
+        goto error;
+    }
     rcc = spice_malloc0(size);
     rcc->client = client;
     rcc->channel = channel;
@@ -1241,7 +1263,11 @@ RedChannelClient *red_channel_client_create_dummy(int size,
     rcc->incoming.serial = 1;
 
     red_channel_add_client(channel, rcc);
+    pthread_mutex_unlock(&client->lock);
     return rcc;
+error:
+    pthread_mutex_unlock(&client->lock);
+    return NULL;
 }
 
 void red_channel_client_destroy_dummy(RedChannelClient *rcc)
@@ -1454,13 +1480,29 @@ void red_client_destroy(RedClient *client)
     free(client);
 }
 
+/* client->lock should be locked */
+static RedChannelClient *red_client_get_channel(RedClient *client, int type, int id)
+{
+    RingItem *link;
+    RedChannelClient *rcc;
+    RedChannelClient *ret = NULL;
+
+    RING_FOREACH(link, &client->channels) {
+        rcc = SPICE_CONTAINEROF(link, RedChannelClient, client_link);
+        if (rcc->channel->type == type && rcc->channel->id == id) {
+            ret = rcc;
+            break;
+        }
+    }
+    return ret;
+}
+
+/* client->lock should be locked */
 static void red_client_add_channel(RedClient *client, RedChannelClient *rcc)
 {
     spice_assert(rcc && client);
-    pthread_mutex_lock(&client->lock);
     ring_add(&client->channels, &rcc->client_link);
     client->channels_num++;
-    pthread_mutex_unlock(&client->lock);
 }
 
 MainChannelClient *red_client_get_main(RedClient *client) {


More information about the Spice-commits mailing list