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 <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <[email protected]>
Gerrit-Reviewer: dexter <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: osmith <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-MessageType: merged

Reply via email to