/* * @msg: the complete incoming message, whose header to decode * * Decodes the header part of the message, but does not * validate the decoded fields in the header. It expects * bufferLength to refer to length of the data packet. Upon * return bufferOffset will refer to the amount of the packet * consumed by decoding of the header. * * returns 0 if successfully decoded, -1 upon fatal error */ int virNetMessageDecodeHeader(virNetMessagePtr msg) { XDR xdr; int ret = -1; if (msg->bufferLength < VIR_NET_MESSAGE_LEN_MAX) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to decode header until len is received")); return -1; } msg->bufferOffset = VIR_NET_MESSAGE_LEN_MAX; /* Parse the header. */ xdrmem_create(&xdr, msg->buffer + msg->bufferOffset, msg->bufferLength - msg->bufferOffset, XDR_DECODE); if (!xdr_virNetMessageHeader(&xdr, &msg->header)) { virReportError(VIR_ERR_RPC, "%s", _("Unable to decode message header")); goto cleanup; } msg->bufferOffset += xdr_getpos(&xdr); ret = 0; cleanup: xdr_destroy(&xdr); return ret; }
/* * @msg: the outgoing message, whose header to encode * * Encodes the length word and header of the message, setting the * message offset ready to encode the payload. Leaves space * for the length field later. Upon return bufferLength will * refer to the total available space for message, while * bufferOffset will refer to current space used by header * * returns 0 if successfully encoded, -1 upon fatal error */ int virNetMessageEncodeHeader(virNetMessagePtr msg) { XDR xdr; int ret = -1; unsigned int len = 0; msg->bufferLength = VIR_NET_MESSAGE_MAX + VIR_NET_MESSAGE_LEN_MAX; if (VIR_REALLOC_N(msg->buffer, msg->bufferLength) < 0) { virReportOOMError(); return ret; } msg->bufferOffset = 0; /* Format the header. */ xdrmem_create(&xdr, msg->buffer, msg->bufferLength, XDR_ENCODE); /* The real value is filled in shortly */ if (!xdr_u_int(&xdr, &len)) { virReportError(VIR_ERR_RPC, "%s", _("Unable to encode message length")); goto cleanup; } if (!xdr_virNetMessageHeader(&xdr, &msg->header)) { virReportError(VIR_ERR_RPC, "%s", _("Unable to encode message header")); goto cleanup; } len = xdr_getpos(&xdr); xdr_setpos(&xdr, 0); /* Fill in current length - may be re-written later * if a payload is added */ if (!xdr_u_int(&xdr, &len)) { virReportError(VIR_ERR_RPC, "%s", _("Unable to re-encode message length")); goto cleanup; } msg->bufferOffset += len; ret = 0; cleanup: xdr_destroy(&xdr); return ret; }