pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-netif/+/34078 )
Change subject: stream_srv: Handle ESHUTDOWN and other write() errors destroying the socket ......................................................................
stream_srv: Handle ESHUTDOWN and other write() errors destroying the socket
If internal send() fails with a fatal error, it should destroy the socket. The user will know about the event through the close_cb() called during osmo_stream_srv_destroy().
As a result, the socket is not closed when receiving SHUTDOWN by the peer (through SCTP MSG_NOTIFICATION), but keep it alive since the socket can still keep receiving data from the peer. Only fail if write() to that read-only socket is attempted.
Related: OS#6134 Change-Id: I84ddebabdffe47733cb529bcfebec8757e6a172b --- M src/stream_srv.c 1 file changed, 34 insertions(+), 4 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve osmith: Looks good to me, but someone else must approve pespin: Looks good to me, approved
diff --git a/src/stream_srv.c b/src/stream_srv.c index be43a80..cccb811 100644 --- a/src/stream_srv.c +++ b/src/stream_srv.c @@ -588,8 +588,18 @@ return; }
- if (ret == -1) /* send(): On error -1 is returned, and errno is set appropriately */ - LOGSSRV(conn, LOGL_ERROR, "error to send: %s\n", strerror(errno)); + if (ret == -1) {/* send(): On error -1 is returned, and errno is set appropriately */ + int err = errno; + LOGSSRV(conn, LOGL_ERROR, "send(len=%u) error: %s\n", msgb_length(msg), strerror(err)); + if (err == EAGAIN) { + /* Re-add at the start of the queue to re-attempt: */ + llist_add(&msg->list, &conn->tx_queue); + return; + } + msgb_free(msg); + osmo_stream_srv_destroy(conn); + return; + }
msgb_free(msg);
@@ -877,8 +887,9 @@ break; case SCTP_SHUTDOWN_EVENT: LOGP(DLINP, LOGL_DEBUG, "===> SHUTDOWN EVT\n"); - /* Handle this like a regular disconnect */ - return 0; + /* RFC6458 3.1.4: Any attempt to send more data will cause sendmsg() + * to return with an ESHUTDOWN error. */ + break; } return -EAGAIN; }