From: Lennart Poettering Date: Wed, 11 Oct 2023 14:51:30 +0000 (+0200) Subject: varlink: automatically send ExpectedMore error message back when we were called witho... X-Git-Tag: v255-rc1~267^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=47c9bbb1abff0baa30ef0a12388c4711ccb5f55e;p=thirdparty%2Fsystemd.git varlink: automatically send ExpectedMore error message back when we were called without more=true set, but need it Various Varlink calls only make sense if they are called with more=true (i.e. in a mode where multiple replies are expected to be sent). If a method call assumes it is called with more (manifested in the fact it calls varlink_notify(), the call to reply to such messages) let's return a recognizable error code for the violated expectation. This adds a new error for this, org.varlink.service.ExpectedMore. Note we are squatting the official org.varlink.service namespace, but for such a basic thing it makes sense to add it there. --- diff --git a/src/shared/varlink-org.varlink.service.c b/src/shared/varlink-org.varlink.service.c index 52ba99dd2bd..36dc68fd262 100644 --- a/src/shared/varlink-org.varlink.service.c +++ b/src/shared/varlink-org.varlink.service.c @@ -32,6 +32,8 @@ static VARLINK_DEFINE_ERROR( static VARLINK_DEFINE_ERROR(PermissionDenied); +static VARLINK_DEFINE_ERROR(ExpectedMore); + /* As per https://varlink.org/Service */ VARLINK_DEFINE_INTERFACE( org_varlink_service, @@ -42,4 +44,5 @@ VARLINK_DEFINE_INTERFACE( &vl_error_MethodNotFound, &vl_error_MethodNotImplemented, &vl_error_InvalidParameter, - &vl_error_PermissionDenied); + &vl_error_PermissionDenied, + &vl_error_ExpectedMore); diff --git a/src/shared/varlink.c b/src/shared/varlink.c index 121de882bbf..8eeac4a49fd 100644 --- a/src/shared/varlink.c +++ b/src/shared/varlink.c @@ -2275,6 +2275,12 @@ int varlink_notify(Varlink *v, JsonVariant *parameters) { if (v->state == VARLINK_DISCONNECTED) return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); + + /* If we want to reply with a notify connection but the caller didn't set "more", then return an + * error indicating that we expected to be called with "more" set */ + if (IN_SET(v->state, VARLINK_PROCESSING_METHOD, VARLINK_PENDING_METHOD)) + return varlink_error(v, VARLINK_ERROR_EXPECTED_MORE, NULL); + if (!IN_SET(v->state, VARLINK_PROCESSING_METHOD_MORE, VARLINK_PENDING_METHOD_MORE)) return varlink_log_errno(v, SYNTHETIC_ERRNO(EBUSY), "Connection busy."); diff --git a/src/shared/varlink.h b/src/shared/varlink.h index 5fe529c8532..e5541d3ce5f 100644 --- a/src/shared/varlink.h +++ b/src/shared/varlink.h @@ -214,3 +214,4 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(VarlinkServer *, varlink_server_unref); /* These are errors we came up with and squatted the namespace with */ #define VARLINK_ERROR_PERMISSION_DENIED "org.varlink.service.PermissionDenied" +#define VARLINK_ERROR_EXPECTED_MORE "org.varlink.service.ExpectedMore"