jolly has uploaded this change for review. (
https://gerrit.osmocom.org/c/libosmocore/+/40584?usp=email )
Change subject: osmo-io: Append received message to pending message segment
......................................................................
osmo-io: Append received message to pending message segment
If there is pending data of an incomplete segmented message, received
data will be appended to this message to complete it. Previously, the
message buffer with incomplete data was reused for subsequent reading
of more data. This does not work, if multiple read elements and
buffers are submitted to an io_uring. This will be done in later
patches.
When the segmentation process finds incomplete message, it will allocate
a message buffer of maximum size + the size of the pending data. This
allows received data to be appended without the risk of buffer
overflows.
Change-Id: I08df9736ccc5e9a7df61ca6dcf94629ee010752f
---
M src/core/osmo_io.c
M src/core/osmo_io_internal.h
M src/core/osmo_io_poll.c
M src/core/osmo_io_uring.c
4 files changed, 23 insertions(+), 29 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/84/40584/1
diff --git a/src/core/osmo_io.c b/src/core/osmo_io.c
index aaf7bcc..7de8479 100644
--- a/src/core/osmo_io.c
+++ b/src/core/osmo_io.c
@@ -174,36 +174,19 @@
talloc_free(msghdr);
}
-/*! convenience wrapper to call msgb_alloc with parameters from osmo_io_fd */
-struct msgb *iofd_msgb_alloc(struct osmo_io_fd *iofd)
+/*! convenience wrapper to call msgb_alloc with parameters from osmo_io_fd (with extra
size) */
+struct msgb *iofd_msgb_alloc2(struct osmo_io_fd *iofd, size_t extra)
{
uint16_t headroom = iofd->msgb_alloc.headroom;
- OSMO_ASSERT(iofd->msgb_alloc.size <= 0xffff - headroom);
- return msgb_alloc_headroom_c(iofd, iofd->msgb_alloc.size + headroom, headroom,
"osmo_io_msgb");
+ OSMO_ASSERT(iofd->msgb_alloc.size + extra <= 0xffff - headroom);
+ return msgb_alloc_headroom_c(iofd, iofd->msgb_alloc.size + extra + headroom,
headroom, "osmo_io_msgb");
}
-/*! return the pending msgb in iofd or NULL if there is none*/
-struct msgb *iofd_msgb_pending(struct osmo_io_fd *iofd)
+/*! convenience wrapper to call msgb_alloc with parameters from osmo_io_fd */
+struct msgb *iofd_msgb_alloc(struct osmo_io_fd *iofd)
{
- struct msgb *msg = NULL;
-
- msg = iofd->pending;
- iofd->pending = NULL;
-
- return msg;
-}
-
-/*! Return the pending msgb or allocate and return a new one */
-struct msgb *iofd_msgb_pending_or_alloc(struct osmo_io_fd *iofd)
-{
- struct msgb *msg = NULL;
-
- msg = iofd_msgb_pending(iofd);
- if (!msg)
- msg = iofd_msgb_alloc(iofd);
-
- return msg;
+ return iofd_msgb_alloc2(iofd, 0);
}
/*! Enqueue a message to be sent.
@@ -317,7 +300,7 @@
/* msgb contains more than one segment */
/* Copy the trailing data over */
- msg_pending = iofd_msgb_alloc(iofd);
+ msg_pending = iofd_msgb_alloc2(iofd, extra_len);
memcpy(msgb_data(msg_pending), data + expected_len, extra_len);
msgb_put(msg_pending, extra_len);
*pending_out = msg_pending;
@@ -348,6 +331,18 @@
return;
}
+ /* If we have a pending message, append the received message.
+ * The pending message was allocated large enough so that a received
+ * message with maximum size can be appended. */
+ if (OSMO_UNLIKELY(iofd->pending)) {
+ OSMO_ASSERT(msgb_tailroom(iofd->pending) >= msgb_length(msg));
+ memcpy(iofd->pending->tail, msgb_data(msg), msgb_length(msg));
+ msgb_put(iofd->pending, msgb_length(msg));
+ msgb_free(msg);
+ msg = iofd->pending;
+ iofd->pending = NULL;
+ }
+
do {
pending = NULL;
res = iofd_handle_segmentation(iofd, msg, &pending);
diff --git a/src/core/osmo_io_internal.h b/src/core/osmo_io_internal.h
index a4b0749..10c136b 100644
--- a/src/core/osmo_io_internal.h
+++ b/src/core/osmo_io_internal.h
@@ -153,9 +153,8 @@
struct iofd_msghdr *iofd_msghdr_alloc(struct osmo_io_fd *iofd, enum iofd_msg_action
action, struct msgb *msg, size_t cmsg_size);
void iofd_msghdr_free(struct iofd_msghdr *msghdr);
+struct msgb *iofd_msgb_alloc2(struct osmo_io_fd *iofd, size_t extra);
struct msgb *iofd_msgb_alloc(struct osmo_io_fd *iofd);
-struct msgb *iofd_msgb_pending(struct osmo_io_fd *iofd);
-struct msgb *iofd_msgb_pending_or_alloc(struct osmo_io_fd *iofd);
void iofd_handle_recv(struct osmo_io_fd *iofd, struct msgb *msg, int rc, struct
iofd_msghdr *msghdr);
void iofd_handle_send_completion(struct osmo_io_fd *iofd, int rc, struct iofd_msghdr
*msghdr);
diff --git a/src/core/osmo_io_poll.c b/src/core/osmo_io_poll.c
index 8782adf..466973d 100644
--- a/src/core/osmo_io_poll.c
+++ b/src/core/osmo_io_poll.c
@@ -50,7 +50,7 @@
if (what & OSMO_FD_READ) {
struct iofd_msghdr hdr;
- msg = iofd_msgb_pending_or_alloc(iofd);
+ msg = iofd_msgb_alloc(iofd);
if (!msg) {
LOGPIO(iofd, LOGL_ERROR, "Could not allocate msgb for reading\n");
OSMO_ASSERT(0);
diff --git a/src/core/osmo_io_uring.c b/src/core/osmo_io_uring.c
index fc60b51..26e89d7 100644
--- a/src/core/osmo_io_uring.c
+++ b/src/core/osmo_io_uring.c
@@ -147,7 +147,7 @@
struct iofd_msghdr *msghdr;
struct io_uring_sqe *sqe;
- msg = iofd_msgb_pending_or_alloc(iofd);
+ msg = iofd_msgb_alloc(iofd);
if (!msg) {
LOGPIO(iofd, LOGL_ERROR, "Could not allocate msgb for reading\n");
OSMO_ASSERT(0);
--
To view, visit
https://gerrit.osmocom.org/c/libosmocore/+/40584?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I08df9736ccc5e9a7df61ca6dcf94629ee010752f
Gerrit-Change-Number: 40584
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <andreas(a)eversberg.eu>