summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2017-02-15 09:49:21 +0100
committerWim Taymans <wtaymans@redhat.com>2017-02-15 10:00:39 +0100
commit833f5e6592da388f457c7fde8d3d9a9040384762 (patch)
treed3080e0055691514ab636881ade6bf1c2b6fb829
parentd90b38844ce62eef8c589fb51d2641afa858995d (diff)
protocol-native: keep track of pending access checksaccess-hooks-core
Keep track of pending access checks and cancel/free them when the connection is unlinked. We don't need to keep a ref to the pdispatch object anymore now.
-rw-r--r--src/pulsecore/protocol-native.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 30c4fcdb5..766451953 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -168,6 +168,17 @@ typedef struct upload_stream {
#define UPLOAD_STREAM(o) (upload_stream_cast(o))
PA_DEFINE_PRIVATE_CLASS(upload_stream, output_stream);
+struct native_access_data {
+ pa_access_data d;
+
+ pa_pdispatch *pdispatch;
+ PA_LLIST_FIELDS(struct native_access_data);
+ uint32_t command;
+ uint32_t tag;
+ pa_tagstruct *tagstruct;
+ pa_native_connection *connection;
+};
+
struct pa_native_connection {
pa_msgobject parent;
pa_native_protocol *protocol;
@@ -189,11 +200,21 @@ struct pa_native_connection {
pa_subscription *subscription;
pa_time_event *auth_timeout_event;
pa_srbchannel *srbpending;
+ PA_LLIST_HEAD(struct native_access_data, access_datas);
};
#define PA_NATIVE_CONNECTION(o) (pa_native_connection_cast(o))
PA_DEFINE_PRIVATE_CLASS(pa_native_connection, pa_msgobject);
+static void access_data_free(struct native_access_data *data) {
+ PA_LLIST_REMOVE(struct native_access_data, data->connection->access_datas, data);
+ if (data->d.free_cb)
+ data->d.free_cb(data->d.userdata);
+ if (data->tagstruct)
+ pa_tagstruct_free(data->tagstruct);
+ pa_xfree(data);
+};
+
struct pa_native_protocol {
PA_REFCNT_DECLARE;
@@ -1188,6 +1209,9 @@ static void native_connection_unlink(pa_native_connection *c) {
if (c->srbpending)
pa_srbchannel_free(c->srbpending);
+ while (c->access_datas)
+ access_data_free(c->access_datas);
+
while ((r = pa_idxset_first(c->record_streams, NULL)))
record_stream_unlink(r);
@@ -4850,24 +4874,6 @@ static void command_set_port_latency_offset(pa_pdispatch *pd, uint32_t command,
pa_pstream_send_simple_ack(c->pstream, tag);
}
-typedef struct native_access_data {
- pa_access_data d;
-
- pa_pdispatch *pd;
- uint32_t command;
- uint32_t tag;
- pa_tagstruct *tagstruct;
- pa_native_connection *connection;
-} native_access_data;
-
-static void access_data_free(native_access_data *data) {
- if (data->pd)
- pa_pdispatch_unref(data->pd);
- if (data->tagstruct)
- pa_tagstruct_free(data->tagstruct);
- pa_xfree(data);
-}
-
static const pa_pdispatch_cb_t access_granted_table[PA_COMMAND_MAX] = {
[PA_COMMAND_CREATE_PLAYBACK_STREAM] = command_create_playback_stream,
[PA_COMMAND_CREATE_RECORD_STREAM] = command_create_record_stream,
@@ -4876,7 +4882,7 @@ static const pa_pdispatch_cb_t access_granted_table[PA_COMMAND_MAX] = {
};
static void check_access_complete_cb(pa_access_data *data, pa_access_result_t res) {
- native_access_data *d = (native_access_data *) data;
+ struct native_access_data *d = (struct native_access_data *) data;
pa_native_connection *c = d->connection;
uint32_t command, tag;
@@ -4887,7 +4893,7 @@ static void check_access_complete_cb(pa_access_data *data, pa_access_result_t re
goto finish;
}
- access_granted_table[d->command](d->pd, d->command, d->tag, d->tagstruct, d->connection);
+ access_granted_table[d->command](d->pdispatch, d->command, d->tag, d->tagstruct, d->connection);
finish:
access_data_free(d);
@@ -4902,7 +4908,7 @@ static const pa_access_hook_t access_table[PA_COMMAND_MAX] = {
static void check_command_access(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
- native_access_data *data;
+ struct native_access_data *data;
pa_access_result_t res;
pa_native_connection_assert_ref(c);
@@ -4912,7 +4918,7 @@ static void check_command_access(pa_pdispatch *pd, uint32_t command, uint32_t ta
return;
}
- data = pa_xnew0 (native_access_data, 1);
+ data = pa_xnew0 (struct native_access_data, 1);
data->d.client_index = c->client->index;
data->d.object_index = PA_INVALID_INDEX;
data->d.event = 0;
@@ -4923,11 +4929,12 @@ static void check_command_access(pa_pdispatch *pd, uint32_t command, uint32_t ta
if (res == PA_ACCESS_ASYNC_CHECK) {
/* async, take a copy of the current state and wait for complete_cb */
data->d.complete_cb = check_access_complete_cb;
- data->pd = pd ? pa_pdispatch_ref (pd) : NULL;
+ data->pdispatch = pd;
data->command = command;
data->tag = tag;
data->tagstruct = t ? pa_tagstruct_copy (t) : NULL;
data->connection = c;
+ PA_LLIST_PREPEND(struct native_access_data, c->access_datas, data);
} else if (res == PA_ACCESS_DENIED) {
pa_xfree(data);
pa_pstream_send_error(c->pstream, tag, PA_ERR_ACCESS);
@@ -5262,6 +5269,8 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati
c->authorized = false;
c->srbpending = NULL;
+ PA_LLIST_HEAD_INIT(struct native_access_data, c->access_datas);
+
if (o->auth_anonymous) {
pa_log_info("Client authenticated anonymously.");
c->authorized = true;