int virNetClientStreamSendPacket(virNetClientStreamPtr st, virNetClientPtr client, int status, const char *data, size_t nbytes) { virNetMessagePtr msg; VIR_DEBUG("st=%p status=%d data=%p nbytes=%zu", st, status, data, nbytes); if (!(msg = virNetMessageNew(false))) return -1; virObjectLock(st); msg->header.prog = virNetClientProgramGetProgram(st->prog); msg->header.vers = virNetClientProgramGetVersion(st->prog); msg->header.status = status; msg->header.type = VIR_NET_STREAM; msg->header.serial = st->serial; msg->header.proc = st->proc; virObjectUnlock(st); if (virNetMessageEncodeHeader(msg) < 0) goto error; /* Data packets are async fire&forget, but OK/ERROR packets * need a synchronous confirmation */ if (status == VIR_NET_CONTINUE) { if (virNetMessageEncodePayloadRaw(msg, data, nbytes) < 0) goto error; if (virNetClientSendNoReply(client, msg) < 0) goto error; } else { if (virNetMessageEncodePayloadRaw(msg, NULL, 0) < 0) goto error; if (virNetClientSendWithReply(client, msg) < 0) goto error; } virNetMessageFree(msg); return nbytes; error: virNetMessageFree(msg); return -1; }
int virNetServerProgramSendStreamData(virNetServerProgramPtr prog, virNetServerClientPtr client, virNetMessagePtr msg, int procedure, unsigned int serial, const char *data, size_t len) { VIR_DEBUG("client=%p msg=%p data=%p len=%zu", client, msg, data, len); /* Return header. We're reusing same message object, so * only need to tweak type/status fields */ msg->header.prog = prog->program; msg->header.vers = prog->version; msg->header.proc = procedure; msg->header.type = VIR_NET_STREAM; msg->header.serial = serial; /* * NB * data != NULL + len > 0 => VIR_NET_CONTINUE (Sending back data) * data != NULL + len == 0 => VIR_NET_CONTINUE (Sending read EOF) * data == NULL => VIR_NET_OK (Sending finish handshake confirmation) */ msg->header.status = data ? VIR_NET_CONTINUE : VIR_NET_OK; if (virNetMessageEncodeHeader(msg) < 0) return -1; if (data && len) { if (virNetMessageEncodePayloadRaw(msg, data, len) < 0) return -1; } else { if (virNetMessageEncodePayloadEmpty(msg) < 0) return -1; } VIR_DEBUG("Total %zu", msg->bufferLength); return virNetServerClientSendMessage(client, msg); }