From df5b1e17a543b3b72bf23f3dde63794a4fea6fe2 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 14 Oct 2022 20:39:40 +0300 Subject: msgb: introduce extended copy functions Those are similar to existing *msgb_alloc*() functions but allows to change the size of destination msgb provided it fits the data from source msgb. Change-Id: I36d4c16241d19f0f73c325be4d0e0bdef6813615 Signed-off-by: Max --- include/osmocom/core/msgb.h | 2 ++ src/msgb.c | 54 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index 1e2b0237..3fdb189d 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -70,6 +70,8 @@ extern int msgb_resize_area(struct msgb *msg, uint8_t *area, int old_size, int new_size); extern struct msgb *msgb_copy(const struct msgb *msg, const char *name); extern struct msgb *msgb_copy_c(const void *ctx, const struct msgb *msg, const char *name); +extern struct msgb *msgb_copy_resize(const struct msgb *msg, uint16_t new_len, const char *name); +extern struct msgb *msgb_copy_resize_c(const void *ctx, const struct msgb *msg, uint16_t new_len, const char *name); static int msgb_test_invariant(const struct msgb *msg) __attribute__((pure)); /*! Free all msgbs from a queue built with msgb_enqueue(). diff --git a/src/msgb.c b/src/msgb.c index 0881a55d..713510c6 100644 --- a/src/msgb.c +++ b/src/msgb.c @@ -314,24 +314,29 @@ void *msgb_talloc_ctx_init(void *root_ctx, unsigned int pool_size) return tall_msgb_ctx; } -/*! Copy an msgb. +/*! Copy an msgb with memory reallocation. * - * This function allocates a new msgb, copies the data buffer of msg, - * and adjusts the pointers (incl l1h-l4h) accordingly. The cb part - * is not copied. + * This function allocates a new msgb with new_len size, copies the data buffer of msg, + * and adjusts the pointers (incl l1h-l4h) accordingly. The cb part is not copied. + * \param[in] ctx talloc context on which allocation happens * \param[in] msg The old msgb object - * \param[in] name Human-readable name to be associated with msgb + * \param[in] new_len The length of new msgb object + * \param[in] name Human-readable name to be associated with new msgb */ -struct msgb *msgb_copy_c(const void *ctx, const struct msgb *msg, const char *name) +struct msgb *msgb_copy_resize_c(const void *ctx, const struct msgb *msg, uint16_t new_len, const char *name) { struct msgb *new_msg; - new_msg = msgb_alloc_c(ctx, msg->data_len, name); - if (!new_msg) + if (new_len < msgb_length(msg)) { + LOGP(DLGLOBAL, LOGL_ERROR, + "Data from old msgb (%u bytes) won't fit into new msgb (%u bytes) after reallocation\n", + msgb_length(msg), new_len); return NULL; + } - /* copy data */ - memcpy(new_msg->_data, msg->_data, new_msg->data_len); + new_msg = msgb_alloc_c(ctx, new_len, name); + if (!new_msg) + return NULL; /* copy header */ new_msg->len = msg->len; @@ -339,6 +344,9 @@ struct msgb *msgb_copy_c(const void *ctx, const struct msgb *msg, const char *na new_msg->head += msg->head - msg->_data; new_msg->tail += msg->tail - msg->_data; + /* copy data */ + memcpy(new_msg->data, msg->data, msgb_length(msg)); + if (msg->l1h) new_msg->l1h = new_msg->_data + (msg->l1h - msg->_data); if (msg->l2h) @@ -351,6 +359,32 @@ struct msgb *msgb_copy_c(const void *ctx, const struct msgb *msg, const char *na return new_msg; } +/*! Copy an msgb with memory reallocation. + * + * This function allocates a new msgb with new_len size, copies the data buffer of msg, + * and adjusts the pointers (incl l1h-l4h) accordingly. The cb part is not copied. + * \param[in] msg The old msgb object + * \param[in] name Human-readable name to be associated with new msgb + */ +struct msgb *msgb_copy_resize(const struct msgb *msg, uint16_t new_len, const char *name) +{ + return msgb_copy_resize_c(tall_msgb_ctx, msg, new_len, name); +} + +/*! Copy an msgb. + * + * This function allocates a new msgb, copies the data buffer of msg, + * and adjusts the pointers (incl l1h-l4h) accordingly. The cb part + * is not copied. + * \param[in] ctx talloc context on which allocation happens + * \param[in] msg The old msgb object + * \param[in] name Human-readable name to be associated with msgb + */ +struct msgb *msgb_copy_c(const void *ctx, const struct msgb *msg, const char *name) +{ + return msgb_copy_resize_c(ctx, msg, msg->data_len, name); +} + /*! Copy an msgb. * * This function allocates a new msgb, copies the data buffer of msg, -- cgit v1.2.3