pipewire/src/modules/module-protocol-native/protocol-footer.h

61 lines
2.1 KiB
C
Raw Normal View History

/* PipeWire
*
* Copyright © 2018 Wim Taymans
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* Protocol footer.
*
* For passing around general state data that is not associated with
* messages sent to objects.
*/
enum {
impl-core/protocol-native: use generation counter for global registry Some client messages have bare ids (as opposed to proxies/resources), eg. as in pw_registry_bind/destroy. If the client is processing messages late, these may refer to an object that was already removed, and the id may now refers to a differnt objects. I.e. the following race condition needs to be resolved: server client Global 1 (gen. 1) Global 1 Global 1 remove Global 1 (gen. 2) Bind/destroy 1 Where the client would bind/destroy the wrong global, since it did not yet see the messages for the second one. To keep track of which object the client means, the server keeps track of the "generation number" of its global registry, and what generation the client is at. Each global remembers at what generation of registry they were registered. When processing the messages that use bare ids, check the registry generation of the client, to know whether the message refers to a stale global that was already removed. Messages where client sends bare ids to server are: pw_registry_bind, pw_registry_destroy, metadata_set_property In pw_registry_* do the staleness check directly. Also add staleness check in pw_impl_client_check_permissions, so that also the metadata case is handled. The generation numbers are passed around in message footers, but only if they have changed. When the generation number changes on server, we send the updated value to the client in a message footer. When client has received an update value, it will send the value back in the footer of the next message it sends to the server. Based on: Wim Taymans <wtaymans@redhat.com> "impl-core: check serial number"
2021-11-08 12:26:37 +01:00
FOOTER_PROXY_OPCODE_GENERATION = 0,
FOOTER_PROXY_OPCODE_LAST
};
enum {
impl-core/protocol-native: use generation counter for global registry Some client messages have bare ids (as opposed to proxies/resources), eg. as in pw_registry_bind/destroy. If the client is processing messages late, these may refer to an object that was already removed, and the id may now refers to a differnt objects. I.e. the following race condition needs to be resolved: server client Global 1 (gen. 1) Global 1 Global 1 remove Global 1 (gen. 2) Bind/destroy 1 Where the client would bind/destroy the wrong global, since it did not yet see the messages for the second one. To keep track of which object the client means, the server keeps track of the "generation number" of its global registry, and what generation the client is at. Each global remembers at what generation of registry they were registered. When processing the messages that use bare ids, check the registry generation of the client, to know whether the message refers to a stale global that was already removed. Messages where client sends bare ids to server are: pw_registry_bind, pw_registry_destroy, metadata_set_property In pw_registry_* do the staleness check directly. Also add staleness check in pw_impl_client_check_permissions, so that also the metadata case is handled. The generation numbers are passed around in message footers, but only if they have changed. When the generation number changes on server, we send the updated value to the client in a message footer. When client has received an update value, it will send the value back in the footer of the next message it sends to the server. Based on: Wim Taymans <wtaymans@redhat.com> "impl-core: check serial number"
2021-11-08 12:26:37 +01:00
FOOTER_RESOURCE_OPCODE_GENERATION = 0,
FOOTER_RESOURCE_OPCODE_LAST
};
struct footer_proxy_global_state {
impl-core/protocol-native: use generation counter for global registry Some client messages have bare ids (as opposed to proxies/resources), eg. as in pw_registry_bind/destroy. If the client is processing messages late, these may refer to an object that was already removed, and the id may now refers to a differnt objects. I.e. the following race condition needs to be resolved: server client Global 1 (gen. 1) Global 1 Global 1 remove Global 1 (gen. 2) Bind/destroy 1 Where the client would bind/destroy the wrong global, since it did not yet see the messages for the second one. To keep track of which object the client means, the server keeps track of the "generation number" of its global registry, and what generation the client is at. Each global remembers at what generation of registry they were registered. When processing the messages that use bare ids, check the registry generation of the client, to know whether the message refers to a stale global that was already removed. Messages where client sends bare ids to server are: pw_registry_bind, pw_registry_destroy, metadata_set_property In pw_registry_* do the staleness check directly. Also add staleness check in pw_impl_client_check_permissions, so that also the metadata case is handled. The generation numbers are passed around in message footers, but only if they have changed. When the generation number changes on server, we send the updated value to the client in a message footer. When client has received an update value, it will send the value back in the footer of the next message it sends to the server. Based on: Wim Taymans <wtaymans@redhat.com> "impl-core: check serial number"
2021-11-08 12:26:37 +01:00
uint64_t last_recv_generation;
};
struct footer_resource_global_state {
impl-core/protocol-native: use generation counter for global registry Some client messages have bare ids (as opposed to proxies/resources), eg. as in pw_registry_bind/destroy. If the client is processing messages late, these may refer to an object that was already removed, and the id may now refers to a differnt objects. I.e. the following race condition needs to be resolved: server client Global 1 (gen. 1) Global 1 Global 1 remove Global 1 (gen. 2) Bind/destroy 1 Where the client would bind/destroy the wrong global, since it did not yet see the messages for the second one. To keep track of which object the client means, the server keeps track of the "generation number" of its global registry, and what generation the client is at. Each global remembers at what generation of registry they were registered. When processing the messages that use bare ids, check the registry generation of the client, to know whether the message refers to a stale global that was already removed. Messages where client sends bare ids to server are: pw_registry_bind, pw_registry_destroy, metadata_set_property In pw_registry_* do the staleness check directly. Also add staleness check in pw_impl_client_check_permissions, so that also the metadata case is handled. The generation numbers are passed around in message footers, but only if they have changed. When the generation number changes on server, we send the updated value to the client in a message footer. When client has received an update value, it will send the value back in the footer of the next message it sends to the server. Based on: Wim Taymans <wtaymans@redhat.com> "impl-core: check serial number"
2021-11-08 12:26:37 +01:00
uint64_t last_sent_generation;
};
struct footer_demarshal {
int (*demarshal)(void *object, struct spa_pod_parser *parser);
};
extern const struct footer_demarshal footer_proxy_demarshal[FOOTER_PROXY_OPCODE_LAST];
extern const struct footer_demarshal footer_resource_demarshal[FOOTER_RESOURCE_OPCODE_LAST];
void marshal_proxy_footers(struct footer_proxy_global_state *state, struct pw_proxy *proxy,
struct spa_pod_builder *builder);
void marshal_resource_footers(struct footer_resource_global_state *state, struct pw_resource *resource,
struct spa_pod_builder *builder);