This is a function that handles an incoming STREAM_SKIP packet.
Even though it is not wired up yet, it will be soon. At the
beginning do couple of checks whether server plays nicely and
sent us a STREAM_SKIP packed only after we've enabled sparse
streams. Then decodes the message payload to see how big the hole
is and stores it in passed @length argument.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/rpc/virnetclientstream.c | 63 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/src/rpc/virnetclientstream.c b/src/rpc/virnetclientstream.c
index d7d2b0e..0e982ba 100644
--- a/src/rpc/virnetclientstream.c
+++ b/src/rpc/virnetclientstream.c
@@ -28,6 +28,7 @@
#include "virerror.h"
#include "virlog.h"
#include "virthread.h"
+#include "libvirt_internal.h"
#define VIR_FROM_THIS VIR_FROM_RPC
@@ -55,6 +56,7 @@ struct _virNetClientStream {
bool incomingEOF;
bool skippable; /* User requested skippable stream */
+ unsigned long long skipLength; /* Size of incoming hole in stream. */
virNetClientStreamEventCallback cb;
void *cbOpaque;
@@ -358,6 +360,67 @@ int virNetClientStreamSendPacket(virNetClientStreamPtr st,
return -1;
}
+
+static int ATTRIBUTE_UNUSED
+virNetClientStreamHandleSkip(virNetClientPtr client,
+ virNetClientStreamPtr st)
+{
+ virNetMessagePtr msg;
+ virNetStreamSkip data;
+ int ret = -1;
+
+ VIR_DEBUG("client=%p st=%p", client, st);
+
+ msg = st->rx;
+ memset(&data, 0, sizeof(data));
+
+ /* We should not be called unless there's VIR_NET_STREAM_SKIP
+ * message at the head of the list. But doesn't hurt to check */
+ if (!msg) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No message in the queue"));
+ goto cleanup;
+ }
+
+ if (msg->header.type != VIR_NET_STREAM_SKIP) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Invalid message prog=%d type=%d serial=%u proc=%d"),
+ msg->header.prog,
+ msg->header.type,
+ msg->header.serial,
+ msg->header.proc);
+ goto cleanup;
+ }
+
+ /* Server should not send us VIR_NET_STREAM_SKIP unless we
+ * have requested so. But does not hurt to check ... */
+ if (!st->skippable) {
+ virReportError(VIR_ERR_RPC, "%s",
+ _("Unexpected stream skip"));
+ goto cleanup;
+ }
+
+ if (virNetMessageDecodePayload(msg,
+ (xdrproc_t) xdr_virNetStreamSkip,
+ &data) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Malformed stream skip packet"));
+ goto cleanup;
+ }
+
+ virNetMessageQueueServe(&st->rx);
+ virNetMessageFree(msg);
+ st->skipLength += data.length;
+
+ ret = 0;
+ cleanup:
+ if (ret < 0) {
+ /* Abort stream? */
+ }
+ return ret;
+}
+
+
int virNetClientStreamRecvPacket(virNetClientStreamPtr st,
virNetClientPtr client,
char *data,
--
2.8.4