* For your program to be able to work reliably over a remote
* connection you should split large requests to <= 65536 bytes.
* However, with 0.9.13 this RPC limit has been raised to 1M byte.
+ * Starting with version 1.0.6 the RPC limit has been raised again.
+ * Now large requests up to 16M byte are supported.
*
* Returns: 0 in case of success or -1 in case of failure.
*/
* For your program to be able to work reliably over a remote
* connection you should split large requests to <= 65536 bytes.
* However, with 0.9.13 this RPC limit has been raised to 1M byte.
+ * Starting with version 1.0.6 the RPC limit has been raised again.
+ * Now large requests up to 16M byte are supported.
*
* Returns: 0 in case of success or -1 in case of failure.
*/
* This is an arbitrary limit designed to stop the decoder from trying
* to allocate unbounded amounts of memory when fed with a bad message.
*/
-const REMOTE_STRING_MAX = 1048576;
+const REMOTE_STRING_MAX = 4194304;
/* A long string, which may NOT be NULL. */
typedef string remote_nonnull_string<REMOTE_STRING_MAX>;
* Note applications need to be aware of this limit and issue multiple
* requests for large amounts of data.
*/
-const REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX = 1048576;
+const REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX = 4194304;
/* Maximum length of a memory peek buffer message.
* Note applications need to be aware of this limit and issue multiple
* requests for large amounts of data.
*/
-const REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX = 1048576;
+const REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX = 4194304;
/*
* Maximum length of a security label list.
int ret = -1;
unsigned int len = 0;
- msg->bufferLength = VIR_NET_MESSAGE_MAX + VIR_NET_MESSAGE_LEN_MAX;
+ msg->bufferLength = VIR_NET_MESSAGE_INITIAL + VIR_NET_MESSAGE_LEN_MAX;
if (VIR_REALLOC_N(msg->buffer, msg->bufferLength) < 0) {
virReportOOMError();
return ret;
xdrmem_create(&xdr, msg->buffer + msg->bufferOffset,
msg->bufferLength - msg->bufferOffset, XDR_ENCODE);
- if (!(*filter)(&xdr, data)) {
- virReportError(VIR_ERR_RPC, "%s", _("Unable to encode message payload"));
- goto error;
+ /* Try to encode the payload. If the buffer is too small increase it. */
+ while (!(*filter)(&xdr, data)) {
+ if ((msg->bufferLength - VIR_NET_MESSAGE_LEN_MAX) * 4 > VIR_NET_MESSAGE_MAX) {
+ virReportError(VIR_ERR_RPC, "%s", _("Unable to encode message payload"));
+ goto error;
+ }
+
+ xdr_destroy(&xdr);
+
+ msg->bufferLength = (msg->bufferLength - VIR_NET_MESSAGE_LEN_MAX) * 4 +
+ VIR_NET_MESSAGE_LEN_MAX;
+
+ if (VIR_REALLOC_N(msg->buffer, msg->bufferLength) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ xdrmem_create(&xdr, msg->buffer + msg->bufferOffset,
+ msg->bufferLength - msg->bufferOffset, XDR_ENCODE);
+
+ VIR_DEBUG("Increased message buffer length = %zu", msg->bufferLength);
}
/* Get the length stored in buffer. */
XDR xdr;
unsigned int msglen;
+ /* If the message buffer is too small for the payload increase it accordingly. */
if ((msg->bufferLength - msg->bufferOffset) < len) {
- virReportError(VIR_ERR_RPC,
- _("Stream data too long to send (%zu bytes needed, %zu bytes available)"),
- len, (msg->bufferLength - msg->bufferOffset));
- return -1;
+ if ((msg->bufferOffset + len) > VIR_NET_MESSAGE_MAX) {
+ virReportError(VIR_ERR_RPC,
+ _("Stream data too long to send (%zu bytes needed, %zu bytes available)"),
+ len, (VIR_NET_MESSAGE_MAX - msg->bufferOffset));
+ return -1;
+ }
+
+ msg->bufferLength = msg->bufferOffset + len;
+
+ if (VIR_REALLOC_N(msg->buffer, msg->bufferLength) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ VIR_DEBUG("Increased message buffer length = %zu", msg->bufferLength);
}
memcpy(msg->buffer + msg->bufferOffset, data, len);
struct _virNetMessage {
bool tracked;
- char *buffer; /* Typically VIR_NET_MESSAGE_MAX + VIR_NET_MESSAGE_LEN_MAX */
+ char *buffer; /* Initially VIR_NET_MESSAGE_INITIAL + VIR_NET_MESSAGE_LEN_MAX */
+ /* Maximum VIR_NET_MESSAGE_MAX + VIR_NET_MESSAGE_LEN_MAX */
size_t bufferLength;
size_t bufferOffset;
/*----- Data types. -----*/
+/* Initial message size.
+ * When the message payload is larger this initial size will be
+ * quadrupled until the maximum total message size is reached.
+ */
+const VIR_NET_MESSAGE_INITIAL = 65536;
+
/* Maximum total message size (serialised). */
-const VIR_NET_MESSAGE_MAX = 4194304;
+const VIR_NET_MESSAGE_MAX = 16777216;
/* Size of struct virNetMessageHeader (serialised)*/
const VIR_NET_MESSAGE_HEADER_MAX = 24;
/* Size of message payload */
-const VIR_NET_MESSAGE_PAYLOAD_MAX = 4194280;
+const VIR_NET_MESSAGE_PAYLOAD_MAX = 16777192;
-/* Size of message length field. Not counted in VIR_NET_MESSAGE_MAX */
+/* Size of message length field. Not counted in VIR_NET_MESSAGE_MAX
+ * and VIR_NET_MESSAGE_INITIAL.
+ */
const VIR_NET_MESSAGE_LEN_MAX = 4;
/* Length of long, but not unbounded, strings.
* This is an arbitrary limit designed to stop the decoder from trying
* to allocate unbounded amounts of memory when fed with a bad message.
*/
-const VIR_NET_MESSAGE_STRING_MAX = 1048576;
+const VIR_NET_MESSAGE_STRING_MAX = 4194304;
/* Limit on number of File Descriptors allowed to be
* passed per message
};
/* According to doc to virNetMessageEncodeHeader(&msg):
* msg->buffer will be this long */
- unsigned long msg_buf_size = VIR_NET_MESSAGE_MAX + VIR_NET_MESSAGE_LEN_MAX;
+ unsigned long msg_buf_size = VIR_NET_MESSAGE_INITIAL + VIR_NET_MESSAGE_LEN_MAX;
int ret = -1;
if (!msg) {