proto: separate pre-connection properties into ConfigureProperty

This is primarily for namespacing: where a portal sets some properties
it needs to do so *before* the Connect event. By moving this out to a
different namespace we can separate this easier, avoiding a portal
accidentally sending a property event after it has already passed the fd
to the client.

Fixes #23
This commit is contained in:
Peter Hutterer 2022-09-07 10:07:56 +10:00
parent bc78c24290
commit 29da572dca
6 changed files with 57 additions and 5 deletions

View file

@ -103,6 +103,17 @@ message ConfigureCapabilities {
uint32 allowed_capabilities = 2;
}
/**
* ConfigureProperty *must* be sent before the Connect event. Once the client
* is connected or if sent outside a ConfigureStart/ConfigureFinish
* transaction, this message is ignored.
*/
message ConfigureProperty {
string name = 1;
string value = 2;
uint32 permissions = 3;
}
message Connect {
uint32 version = 1; /* Must be equal or less to the server's GetVersion response */
string name = 2;
@ -236,6 +247,7 @@ message ClientMessage {
ConfigureFinish configure_finish = 101;
ConfigureName configure_name = 102;
ConfigureCapabilities configure_capabilities = 103;
ConfigureProperty configure_property = 104;
}
}

View file

@ -263,6 +263,7 @@ log_wire_message(struct ei *ei, const ClientMessage *msg, int error)
MSG_STRING_CASE(CONFIGURE_FINISH);
MSG_STRING_CASE(CONFIGURE_NAME);
MSG_STRING_CASE(CONFIGURE_CAPABILITIES);
MSG_STRING_CASE(CONFIGURE_PROPERTY);
}
if (message == NULL)
assert(!"Unimplemented message type");

View file

@ -604,6 +604,26 @@ client_msg_configure_capabilities(struct eis_client *client, uint32_t allowed_ca
return 0;
}
static int
client_msg_configure_property(struct eis_client *client,
const char *name, const char *value,
uint32_t permissions)
{
tristate t = client_is_in_configure_transaction(client);
if (tristate_is_finished(t))
return -EPROTO;
/* Once the client is connected, we silently ignore all Configure
requests so a broken portal can't accidentally disconnect a client */
if (tristate_is_connected(t))
return 0;
eis_property_update_from_client(client, name, value, permissions);
return 0;
}
static int
client_msg_connect(struct eis_client *client, uint32_t version,
const char *name, bool is_sender)
@ -674,6 +694,7 @@ static const struct eis_proto_interface intf_state_new = {
.configure_finish = client_msg_configure_finish,
.configure_name = client_msg_configure_name,
.configure_capabilities = client_msg_configure_capabilities,
.configure_property = client_msg_configure_property,
};
/* Client is waiting for us, shouldn't send anything except disconnect */
@ -685,6 +706,7 @@ static const struct eis_proto_interface intf_state_connecting = {
.configure_finish = client_msg_configure_finish,
.configure_name = client_msg_configure_name,
.configure_capabilities = client_msg_configure_capabilities,
.configure_property = client_msg_configure_property,
};
static const struct eis_proto_interface intf_state_connected = {
@ -714,6 +736,7 @@ static const struct eis_proto_interface intf_state_connected = {
.configure_finish = client_msg_configure_finish,
.configure_name = client_msg_configure_name,
.configure_capabilities = client_msg_configure_capabilities,
.configure_property = client_msg_configure_property,
};
static const struct eis_proto_interface *interfaces[] = {

View file

@ -639,6 +639,11 @@ eis_proto_handle_message(struct eis_client *client,
rc = call(configure_capabilities, client,
proto->configure_capabilities->allowed_capabilities);
break;
case CLIENT_MESSAGE__MSG_CONFIGURE_PROPERTY:
rc = call(configure_property, client, proto->configure_property->name,
proto->configure_property->value[0] ? proto->configure_property->value : NULL,
proto->configure_property->permissions);
break;
default:
rc = -EBADMSG;
break;

View file

@ -67,6 +67,8 @@ struct eis_proto_interface {
int (*configure_finish)(struct eis_client *client);
int (*configure_name)(struct eis_client *client, const char *name);
int (*configure_capabilities)(struct eis_client *client, uint32_t allow);
int (*configure_property)(struct eis_client *client, const char *name,
const char *value, uint32_t permissions);
};
struct eis_proto_requests {

View file

@ -129,13 +129,22 @@ reis_set_property_with_permissions(struct reis *reis,
const char *name, const char *value,
uint32_t permissions)
{
prepare_msg(SET_PROPERTY, SetProperty, set_property);
int rc;
set_property.name = (char*)name;
set_property.value = value ? (char*)value : "";
set_property.permissions = permissions;
if ((rc = reis_start(reis)) != 0)
return rc;
return send_msg(reis->eisfd, &msg);
prepare_msg(CONFIGURE_PROPERTY, ConfigureProperty, configure_property);
configure_property.name = (char*)name;
configure_property.value = value ? (char*)value : "";
configure_property.permissions = permissions;
rc = send_msg(reis->eisfd, &msg);
if (rc == 0)
return rc;
return reis_finish(reis);
}
_public_ int