Add osmo_stream_{cli,srv_link}_set_nodelay() function

Using this function, the user can configure if sockets related to the
respective stream client or server should have the NODELAY socket
option set in order to avoid Nagle algorithm or related algorithms
that may introduce packet delay on the transmitter side.

Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9
---
M include/osmocom/netif/stream.h
M src/stream.c
2 files changed, 67 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/95/2295/2

diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h
index 63eccf8..7afb7af 100644
--- a/include/osmocom/netif/stream.h
+++ b/include/osmocom/netif/stream.h
@@ -16,6 +16,7 @@
 struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx);
 void osmo_stream_srv_link_destroy(struct osmo_stream_srv_link *link);
 
+void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool 
nodelay);
 void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const 
char *addr);
 void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t 
port);
 void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, 
uint16_t proto);
@@ -45,6 +46,7 @@
 /*! \brief Osmocom Stream Client: Single client connection */
 struct osmo_stream_cli;
 
+void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay);
 void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr);
 void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port);
 void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto);
diff --git a/src/stream.c b/src/stream.c
index f5ead17..76886f0 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -9,6 +9,7 @@
 #include <sys/ioctl.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>
 
 #include <osmocom/core/timer.h>
 #include <osmocom/core/select.h>
@@ -75,6 +76,7 @@
 };
 
 #define OSMO_STREAM_CLI_F_RECONF       (1 << 0)
+#define OSMO_STREAM_CLI_F_NODELAY      (1 << 1)
 
 struct osmo_stream_cli {
        struct osmo_fd                  ofd;
@@ -400,6 +402,22 @@
                return ret;
        }
 
+       if (cli->flags & OSMO_STREAM_CLI_F_NODELAY) {
+               int on = 1;
+               switch (cli->proto) {
+               case IPPROTO_TCP:
+                       setsockopt(cli->ofd.fd, SOL_TCP, TCP_NODELAY, &on, 
sizeof(on));
+                       break;
+               case IPPROTO_SCTP:
+                       setsockopt(cli->ofd.fd, SOL_SCTP, SCTP_NODELAY, &on, 
sizeof(on));
+                       break;
+               default:
+                       LOGP(DLINP, LOGL_ERROR, "Unknown protocol %u, cannot 
set NODELAY\n",
+                               cli->proto);
+                       break;
+               }
+       }
+
        cli->ofd.fd = ret;
        if (osmo_fd_register(&cli->ofd) < 0) {
                close(ret);
@@ -409,6 +427,21 @@
        return 0;
 }
 
+/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior
+ *  Setting this to nodelay=true will automatically set the NODELAY
+ *  socket option on any socket established via \ref osmo_stream_cli_open
+ *  or any re-connect.  You have to set this _before_ opening the
+ *  socket.
+ *  \param[in] cli Stream client whose sockets are to be configured
+ *  \param[in] nodelay whether to set (true) NODELAY before connect()
+ */
+void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay)
+{
+       if (nodelay)
+               cli->flags |= OSMO_STREAM_CLI_F_NODELAY;
+       else
+               cli->flags &= ~OSMO_STREAM_CLI_F_NODELAY;
+}
 
 /*! \brief Open connection of an Osmocom stream client
  *  \param[in] cli Stream Client to connect */
@@ -473,6 +506,7 @@
  */
 
 #define OSMO_STREAM_SRV_F_RECONF       (1 << 0)
+#define OSMO_STREAM_SRV_F_NODELAY      (1 << 1)
 
 struct osmo_stream_srv_link {
         struct osmo_fd                  ofd;
@@ -503,6 +537,22 @@
        if (link->proto == IPPROTO_SCTP)
                sctp_sock_activate_events(ret);
 
+       if (link->flags & OSMO_STREAM_SRV_F_NODELAY) {
+               int on = 1;
+               switch (link->proto) {
+               case IPPROTO_SCTP:
+                       setsockopt(ret, SOL_SCTP, SCTP_NODELAY, &on, 
sizeof(on));
+                       break;
+               case IPPROTO_TCP:
+                       setsockopt(ret, SOL_TCP, TCP_NODELAY, &on, sizeof(on));
+                       break;
+               default:
+                       LOGP(DLINP, LOGL_ERROR, "Unknown protocol %u, cannot 
set NODELAY\n",
+                            link->proto);
+                       break;
+               }
+       }
+
        if (link->accept_cb)
                link->accept_cb(link, ret);
 
@@ -532,6 +582,21 @@
        return link;
 }
 
+/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior
+ *  Setting this to nodelay=true will automatically set the NODELAY
+ *  socket option on any socket established via this server link, before
+ *  calling the accept_cb()
+ *  \param[in] link server link whose sockets are to be configured
+ *  \param[in] nodelay whether to set (true) NODELAY after accept
+ */
+void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool 
nodelay)
+{
+       if (nodelay)
+               link->flags |= OSMO_STREAM_SRV_F_NODELAY;
+       else
+               link->flags &= ~OSMO_STREAM_SRV_F_NODELAY;
+}
+
 /*! \brief Set the local address to which we bind
  *  \param[in] link Stream Server Link to modify
  *  \param[in] addr Local IP address

-- 
To view, visit https://gerrit.osmocom.org/2295
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9
Gerrit-PatchSet: 2
Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <lafo...@gnumonks.org>
Gerrit-Reviewer: Jenkins Builder

Reply via email to