aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/netif/stream.h2
-rw-r--r--src/stream.c60
2 files changed, 62 insertions, 0 deletions
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;
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 @@ int osmo_stream_srv_recv(struct osmo_stream_srv *conn, struct msgb *msg);
/*! \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..3bc36a3 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>
@@ -63,6 +64,27 @@ static int sctp_sock_activate_events(int fd)
#endif
}
+static int setsockopt_nodelay(int fd, int proto, int on)
+{
+ int rc;
+
+ switch (proto) {
+ case IPPROTO_SCTP:
+ rc = setsockopt(fd, IPPROTO_SCTP, SCTP_NODELAY, &on, sizeof(on));
+ break;
+ case IPPROTO_TCP:
+ rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+ break;
+ default:
+ rc = -1;
+ LOGP(DLINP, LOGL_ERROR, "Unknown protocol %u, cannot set NODELAY\n",
+ proto);
+ break;
+ }
+ return rc;
+}
+
+
/*
* Client side.
*/
@@ -75,6 +97,7 @@ enum osmo_stream_cli_state {
};
#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 +423,9 @@ int osmo_stream_cli_open2(struct osmo_stream_cli *cli, int reconnect)
return ret;
}
+ if (cli->flags & OSMO_STREAM_CLI_F_NODELAY)
+ setsockopt_nodelay(cli->ofd.fd, cli->proto, 1);
+
cli->ofd.fd = ret;
if (osmo_fd_register(&cli->ofd) < 0) {
close(ret);
@@ -409,6 +435,21 @@ int osmo_stream_cli_open2(struct osmo_stream_cli *cli, int reconnect)
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 +514,7 @@ int osmo_stream_cli_recv(struct osmo_stream_cli *cli, struct msgb *msg)
*/
#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 +545,9 @@ static int osmo_stream_srv_fd_cb(struct osmo_fd *ofd, unsigned int what)
if (link->proto == IPPROTO_SCTP)
sctp_sock_activate_events(ret);
+ if (link->flags & OSMO_STREAM_SRV_F_NODELAY)
+ setsockopt_nodelay(ret, link->proto, 1);
+
if (link->accept_cb)
link->accept_cb(link, ret);
@@ -532,6 +577,21 @@ struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx)
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