diff options
-rw-r--r-- | include/osmocom/netif/stream.h | 2 | ||||
-rw-r--r-- | src/stream.c | 60 |
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 |