pespin has submitted this change. (
https://gerrit.osmocom.org/c/libosmo-netif/+/30722 )
Change subject: stream: Fix tx data dropped upon show socket write
......................................................................
stream: Fix tx data dropped upon show socket write
On some stream socket types like TCP it is expected that the send()
syscall may return a short write, ie not all bytes being copied to the
socket. In that case we need to keep the bytes not copied and attempt to
submit them later.
Related: OS#5836
Change-Id: I3755aada02ceb186fb990604e3496126fe47e1fb
---
M src/stream.c
1 file changed, 22 insertions(+), 12 deletions(-)
Approvals:
Jenkins Builder: Verified
daniel: Looks good to me, but someone else must approve
dexter: Looks good to me, but someone else must approve
osmith: Looks good to me, but someone else must approve
laforge: Looks good to me, approved
pespin: Looks good to me, but someone else must approve
diff --git a/src/stream.c b/src/stream.c
index 503fe3c..feb6c22 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -335,16 +335,14 @@
struct sctp_sndrcvinfo sinfo;
#endif
struct msgb *msg;
- struct llist_head *lh;
int ret;
if (llist_empty(&cli->tx_queue)) {
osmo_fd_write_disable(&cli->ofd);
return 0;
}
- lh = cli->tx_queue.next;
- llist_del(lh);
- msg = llist_entry(lh, struct msgb, list);
+ msg = llist_first_entry(&cli->tx_queue, struct msgb, list);
+ llist_del(&msg->list);
if (!osmo_stream_cli_is_connected(cli)) {
LOGSCLI(cli, LOGL_ERROR, "not connected, dropping data!\n");
@@ -379,13 +377,20 @@
default:
ret = -ENOTSUP;
}
+
+ if (ret >= 0 && ret < msgb_length(msg)) {
+ LOGP(DLINP, LOGL_ERROR, "short send: %d < exp %u\n", ret,
msgb_length(msg));
+ /* Update msgb and re-add it at the start of the queue: */
+ msgb_pull(msg, ret);
+ llist_add(&msg->list, &cli->tx_queue);
+ return 0;
+ }
+
if (ret < 0) {
if (errno == EPIPE || errno == ENOTCONN) {
osmo_stream_cli_reconnect(cli);
}
LOGSCLI(cli, LOGL_ERROR, "error %d to send\n", ret);
- } else if (ret < msgb_length(msg)) {
- LOGP(DLINP, LOGL_ERROR, "short send: %d < exp %u\n", ret,
msgb_length(msg));
}
msgb_free(msg);
@@ -1309,16 +1314,14 @@
struct sctp_sndrcvinfo sinfo;
#endif
struct msgb *msg;
- struct llist_head *lh;
int ret;
if (llist_empty(&conn->tx_queue)) {
osmo_fd_write_disable(&conn->ofd);
return;
}
- lh = conn->tx_queue.next;
- llist_del(lh);
- msg = llist_entry(lh, struct msgb, list);
+ msg = llist_first_entry(&conn->tx_queue, struct msgb, list);
+ llist_del(&msg->list);
LOGP(DLINP, LOGL_DEBUG, "sending %u bytes of data\n", msg->len);
@@ -1349,10 +1352,17 @@
ret = -1;
errno = ENOTSUP;
}
+
+ if (ret >= 0 && ret < msgb_length(msg)) {
+ LOGP(DLINP, LOGL_ERROR, "short send: %d < exp %u\n", ret,
msgb_length(msg));
+ /* Update msgb and re-add it at the start of the queue: */
+ msgb_pull(msg, ret);
+ llist_add(&msg->list, &conn->tx_queue);
+ return;
+ }
+
if (ret == -1) /* send(): On error -1 is returned, and errno is set appropriately */
LOGP(DLINP, LOGL_ERROR, "error to send: %s\n", strerror(errno));
- else if (ret < msgb_length(msg))
- LOGP(DLINP, LOGL_ERROR, "short send: %d < exp %u\n", ret,
msgb_length(msg));
msgb_free(msg);
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-netif/+/30722
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-Change-Id: I3755aada02ceb186fb990604e3496126fe47e1fb
Gerrit-Change-Number: 30722
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de>
Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged