[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 2/9] Decode incoming request header before invoking dispatch code



Separate the decoding of incoming request header out from the
dispatch code. This will allow later code to making dispatcher
routing decisions based on the header field data.

* qemud/dispatch.c, qemud/dispatch.h: Add remoteDecodeClientMessageHeader
  API for decoding the header of a client message. Update the
  remoteDispatchClientRequest method to assume a pre-decoded
  header.
* qemud/qemud.h: Include a 'remote_message_header' field in
  'struct qemud_client_message' for pre-decoded header data
* qemud/qemud.c: Decode the incoming client message header before
  invoking remoteDispatchClientRequest

Signed-off-by: Daniel P. Berrange <berrange redhat com>
---
 qemud/dispatch.c |   96 ++++++++++++++++++++++++++++++++++++-----------------
 qemud/dispatch.h |    3 ++
 qemud/qemud.c    |    3 +-
 qemud/qemud.h    |    2 +
 4 files changed, 72 insertions(+), 32 deletions(-)

diff --git a/qemud/dispatch.c b/qemud/dispatch.c
index d2338fb..127f93b 100644
--- a/qemud/dispatch.c
+++ b/qemud/dispatch.c
@@ -124,13 +124,50 @@ void remoteDispatchConnError (remote_error *rerr,
 
 
 /*
+ * @msg: the complete incoming message, whose header to decode
+ *
+ * Decodes the header part of the client message, but does not
+ * validate the decoded fields in the header.
+ *
+ * returns 0 if successfully decoded, -1 upon fatal error
+ */
+int
+remoteDecodeClientMessageHeader (struct qemud_client_message *msg)
+{
+    XDR xdr;
+    int ret = -1;
+
+    msg->bufferOffset = REMOTE_MESSAGE_HEADER_XDR_LEN;
+
+    /* Parse the header. */
+    xdrmem_create (&xdr,
+                   msg->buffer + msg->bufferOffset,
+                   msg->bufferLength - msg->bufferOffset,
+                   XDR_DECODE);
+
+    if (!xdr_remote_message_header (&xdr, &msg->hdr))
+        goto cleanup;
+
+    msg->bufferOffset += xdr_getpos(&xdr);
+
+    ret = 0;
+
+cleanup:
+    xdr_destroy(&xdr);
+    return ret;
+}
+
+
+/*
  * @server: the unlocked server object
  * @client: the locked client object
- * @msg: the complete incoming message packet
+ * @msg: the complete incoming message packet, with header already decoded
  *
  * This function gets called from qemud when it pulls a incoming
  * remote protocol messsage off the dispatch queue for processing.
  *
+ * The @msg parameter must have had its header decoded already by
+ * calling remoteDecodeClientMessageHeader
  *
  * Returns 0 if the message was dispatched, -1 upon fatal error
  */
@@ -140,7 +177,7 @@ remoteDispatchClientRequest (struct qemud_server *server,
                              struct qemud_client_message *msg)
 {
     XDR xdr;
-    remote_message_header req, rep;
+    remote_message_header rep;
     remote_error rerr;
     dispatch_args args;
     dispatch_ret ret;
@@ -153,36 +190,28 @@ remoteDispatchClientRequest (struct qemud_server *server,
     memset(&ret, 0, sizeof ret);
     memset(&rerr, 0, sizeof rerr);
 
-    /* Parse the header. */
-    xdrmem_create (&xdr,
-                   msg->buffer + REMOTE_MESSAGE_HEADER_XDR_LEN,
-                   msg->bufferLength - REMOTE_MESSAGE_HEADER_XDR_LEN,
-                   XDR_DECODE);
-
-    if (!xdr_remote_message_header (&xdr, &req))
-        goto fatal_error;
 
     /* Check version, etc. */
-    if (req.prog != REMOTE_PROGRAM) {
+    if (msg->hdr.prog != REMOTE_PROGRAM) {
         remoteDispatchFormatError (&rerr,
                                    _("program mismatch (actual %x, expected %x)"),
-                                   req.prog, REMOTE_PROGRAM);
+                                   msg->hdr.prog, REMOTE_PROGRAM);
         goto rpc_error;
     }
-    if (req.vers != REMOTE_PROTOCOL_VERSION) {
+    if (msg->hdr.vers != REMOTE_PROTOCOL_VERSION) {
         remoteDispatchFormatError (&rerr,
                                    _("version mismatch (actual %x, expected %x)"),
-                                   req.vers, REMOTE_PROTOCOL_VERSION);
+                                   msg->hdr.vers, REMOTE_PROTOCOL_VERSION);
         goto rpc_error;
     }
-    if (req.direction != REMOTE_CALL) {
+    if (msg->hdr.direction != REMOTE_CALL) {
         remoteDispatchFormatError (&rerr, _("direction (%d) != REMOTE_CALL"),
-                                   (int) req.direction);
+                                   (int) msg->hdr.direction);
         goto rpc_error;
     }
-    if (req.status != REMOTE_OK) {
+    if (msg->hdr.status != REMOTE_OK) {
         remoteDispatchFormatError (&rerr, _("status (%d) != REMOTE_OK"),
-                                   (int) req.status);
+                                   (int) msg->hdr.status);
         goto rpc_error;
     }
 
@@ -190,11 +219,11 @@ remoteDispatchClientRequest (struct qemud_server *server,
      * except for authentication ones
      */
     if (client->auth) {
-        if (req.proc != REMOTE_PROC_AUTH_LIST &&
-            req.proc != REMOTE_PROC_AUTH_SASL_INIT &&
-            req.proc != REMOTE_PROC_AUTH_SASL_START &&
-            req.proc != REMOTE_PROC_AUTH_SASL_STEP &&
-            req.proc != REMOTE_PROC_AUTH_POLKIT
+        if (msg->hdr.proc != REMOTE_PROC_AUTH_LIST &&
+            msg->hdr.proc != REMOTE_PROC_AUTH_SASL_INIT &&
+            msg->hdr.proc != REMOTE_PROC_AUTH_SASL_START &&
+            msg->hdr.proc != REMOTE_PROC_AUTH_SASL_STEP &&
+            msg->hdr.proc != REMOTE_PROC_AUTH_POLKIT
             ) {
             /* Explicitly *NOT* calling  remoteDispatchAuthError() because
                we want back-compatability with libvirt clients which don't
@@ -204,19 +233,25 @@ remoteDispatchClientRequest (struct qemud_server *server,
         }
     }
 
-    data = remoteGetDispatchData(req.proc);
+    data = remoteGetDispatchData(msg->hdr.proc);
 
     if (!data) {
         remoteDispatchFormatError (&rerr, _("unknown procedure: %d"),
-                                   req.proc);
+                                   msg->hdr.proc);
         goto rpc_error;
     }
 
-    /* De-serialize args off the wire */
+    /* De-serialize payload with args from the wire message */
+    xdrmem_create (&xdr,
+                   msg->buffer + msg->bufferOffset,
+                   msg->bufferLength - msg->bufferOffset,
+                   XDR_DECODE);
     if (!((data->args_filter)(&xdr, &args))) {
+        xdr_destroy (&xdr);
         remoteDispatchFormatError (&rerr, "%s", _("parse args failed"));
         goto rpc_error;
     }
+    xdr_destroy (&xdr);
 
     /* Call function. */
     conn = client->conn;
@@ -241,14 +276,13 @@ remoteDispatchClientRequest (struct qemud_server *server,
     xdr_free (data->args_filter, (char*)&args);
 
 rpc_error:
-    xdr_destroy (&xdr);
 
     /* Return header. */
-    rep.prog = req.prog;
-    rep.vers = req.vers;
-    rep.proc = req.proc;
+    rep.prog = msg->hdr.prog;
+    rep.vers = msg->hdr.vers;
+    rep.proc = msg->hdr.proc;
     rep.direction = REMOTE_REPLY;
-    rep.serial = req.serial;
+    rep.serial = msg->hdr.serial;
     rep.status = rv < 0 ? REMOTE_ERROR : REMOTE_OK;
 
     /* Serialise the return header. */
diff --git a/qemud/dispatch.h b/qemud/dispatch.h
index 9ab6148..db372f1 100644
--- a/qemud/dispatch.h
+++ b/qemud/dispatch.h
@@ -29,6 +29,9 @@
 
 
 int
+remoteDecodeClientMessageHeader (struct qemud_client_message *req);
+
+int
 remoteDispatchClientRequest (struct qemud_server *server,
                              struct qemud_client *client,
                              struct qemud_client_message *req);
diff --git a/qemud/qemud.c b/qemud/qemud.c
index d300c56..c577d88 100644
--- a/qemud/qemud.c
+++ b/qemud/qemud.c
@@ -1458,7 +1458,8 @@ static void *qemudWorker(void *data)
 
         /* This function drops the lock during dispatch,
          * and re-acquires it before returning */
-        if (remoteDispatchClientRequest (server, client, reply) < 0) {
+        if (remoteDecodeClientMessageHeader(reply) < 0 ||
+            remoteDispatchClientRequest (server, client, reply) < 0) {
             VIR_FREE(reply);
             qemudDispatchClientFailure(client);
             client->refs--;
diff --git a/qemud/qemud.h b/qemud/qemud.h
index c8273cb..6597429 100644
--- a/qemud/qemud.h
+++ b/qemud/qemud.h
@@ -85,6 +85,8 @@ struct qemud_client_message {
 
     int async : 1;
 
+    remote_message_header hdr;
+
     struct qemud_client_message *next;
 };
 
-- 
1.6.2.5


-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]