mirror of https://gerrit.osmocom.org/libosmocore
osmo_io: Document expectation that segmentation_cb() can modify msgb
This is used for parsing e.g. the ipa header and setting msg->cb. Guard against segmentation_cb changing msg->data in iofd_handle_segmentation(). Change-Id: Idd2115baae98a7818aabb26232d4423d2d48fb5c
This commit is contained in:
parent
a18f1d7be4
commit
7b59bab794
|
@ -46,7 +46,11 @@ struct osmo_io_ops {
|
||||||
* Needs to return the size of the next message. If it returns
|
* Needs to return the size of the next message. If it returns
|
||||||
* -EAGAIN or a value larger than msgb_length() (message is incomplete)
|
* -EAGAIN or a value larger than msgb_length() (message is incomplete)
|
||||||
* osmo_io will wait for more data to be read. Other negative values
|
* osmo_io will wait for more data to be read. Other negative values
|
||||||
* cause the msg to be discarded. */
|
* cause the msg to be discarded.
|
||||||
|
* If a full message was received (segmentation_cb() returns a value <= msgb_length())
|
||||||
|
* the msgb will be trimmed to size by osmo_io and forwarded to the read call-back. Any
|
||||||
|
* parsing done to the msgb by segmentation_cb() will be preserved for the read_cb()
|
||||||
|
* (e.g. setting lxh or msgb->cb). */
|
||||||
int (*segmentation_cb)(struct msgb *msg);
|
int (*segmentation_cb)(struct msgb *msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -226,6 +226,9 @@ static enum iofd_seg_act iofd_handle_segmentation(struct osmo_io_fd *iofd, struc
|
||||||
int extra_len, received_len;
|
int extra_len, received_len;
|
||||||
struct msgb *msg_pending;
|
struct msgb *msg_pending;
|
||||||
|
|
||||||
|
/* Save the start of message before segmentation_cb (which could change it) */
|
||||||
|
uint8_t *data = msg->data;
|
||||||
|
|
||||||
received_len = msgb_length(msg);
|
received_len = msgb_length(msg);
|
||||||
|
|
||||||
if (!iofd->io_ops.segmentation_cb) {
|
if (!iofd->io_ops.segmentation_cb) {
|
||||||
|
@ -258,12 +261,14 @@ static enum iofd_seg_act iofd_handle_segmentation(struct osmo_io_fd *iofd, struc
|
||||||
/* msgb contains more than one segment */
|
/* msgb contains more than one segment */
|
||||||
/* Copy the trailing data over */
|
/* Copy the trailing data over */
|
||||||
msg_pending = iofd_msgb_alloc(iofd);
|
msg_pending = iofd_msgb_alloc(iofd);
|
||||||
memcpy(msgb_data(msg_pending), msgb_data(msg) + expected_len, extra_len);
|
memcpy(msgb_data(msg_pending), data + expected_len, extra_len);
|
||||||
msgb_put(msg_pending, extra_len);
|
msgb_put(msg_pending, extra_len);
|
||||||
*pending_out = msg_pending;
|
*pending_out = msg_pending;
|
||||||
|
|
||||||
/* Trim the original msgb to size */
|
/* Trim the original msgb to size. Don't use msgb_trim because we need to reference
|
||||||
msgb_trim(msg, expected_len);
|
* msg->data from before it might have been modified by the segmentation_cb(). */
|
||||||
|
msg->len = expected_len;
|
||||||
|
msg->tail = data + expected_len;
|
||||||
return IOFD_SEG_ACT_HANDLE_MORE;
|
return IOFD_SEG_ACT_HANDLE_MORE;
|
||||||
|
|
||||||
defer:
|
defer:
|
||||||
|
|
Loading…
Reference in New Issue