<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/12845">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  osmith: Looks good to me, but someone else must approve
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Deprecate osmo_stream_cli_open2()<br><br>This supposed to be variant of osmo_stream_cli_open() with explicit<br>control over reconnection logic but it's plain broken: doxygen docs<br>contradict the code, actual reconnection logic is affected by timeout<br>parameter directly which is set in different function.<br><br>It seems like we haven't been affected by this so far because we always<br>use it in auto-reconnection mode which is triggered by default due to<br>positive reconnection timeout value (5 sec) automatically used in the<br>absense of explicitly set timeout.<br><br>Looking at commit history, this function already been source of<br>confusion in the past. Instead of trying to fix this mess, let's just<br>deprecate it entirely and properly document use of<br>osmo_stream_cli_set_reconnect_timeout() to control reconnection logic.<br><br>The only known user is libosmo-sccp which won't use it as of<br>0a93a683f3cb8e5977eb4a666ab207db6e7d7af9 commit.<br><br>Change-Id: Id988ed0274b363db049f59cbf6a193727c8c3c8a<br>---<br>M include/osmocom/netif/stream.h<br>M src/stream.c<br>M tests/stream/stream_test.c<br>3 files changed, 120 insertions(+), 7 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h</span><br><span>index 56162e4..f1c160c 100644</span><br><span>--- a/include/osmocom/netif/stream.h</span><br><span>+++ b/include/osmocom/netif/stream.h</span><br><span>@@ -72,7 +72,8 @@</span><br><span> void osmo_stream_cli_destroy(struct osmo_stream_cli *cli);</span><br><span> </span><br><span> int osmo_stream_cli_open(struct osmo_stream_cli *cli);</span><br><span style="color: hsl(0, 100%, 40%);">-int osmo_stream_cli_open2(struct osmo_stream_cli *cli, int reconnect);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_stream_cli_open2(struct osmo_stream_cli *cli, int reconnect) \</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_DEPRECATED("Use osmo_stream_cli_set_reconnect_timeout() or osmo_stream_cli_reconnect() instead");</span><br><span> void osmo_stream_cli_close(struct osmo_stream_cli *cli);</span><br><span> </span><br><span> void osmo_stream_cli_send(struct osmo_stream_cli *cli, struct msgb *msg);</span><br><span>diff --git a/src/stream.c b/src/stream.c</span><br><span>index c4db3d7..3d0b665 100644</span><br><span>--- a/src/stream.c</span><br><span>+++ b/src/stream.c</span><br><span>@@ -166,8 +166,9 @@</span><br><span> void osmo_stream_cli_close(struct osmo_stream_cli *cli);</span><br><span> </span><br><span> /*! \brief Re-connect an Osmocom Stream Client</span><br><span style="color: hsl(0, 100%, 40%);">- *  If re-connection is enabled for this client, we close any existing</span><br><span style="color: hsl(0, 100%, 40%);">- *  connection (if any) and schedule a re-connect timer */</span><br><span style="color: hsl(120, 100%, 40%);">+ *  If re-connection is enabled for this client</span><br><span style="color: hsl(120, 100%, 40%);">+ *  (which is the case unless negative timeout was explicitly set via osmo_stream_cli_set_reconnect_timeout() call),</span><br><span style="color: hsl(120, 100%, 40%);">+ *  we close any existing connection (if any) and schedule a re-connect timer */</span><br><span> void osmo_stream_cli_reconnect(struct osmo_stream_cli *cli)</span><br><span> {</span><br><span>      osmo_stream_cli_close(cli);</span><br><span>@@ -391,7 +392,7 @@</span><br><span> </span><br><span> /*! \brief Set the reconnect time of the stream client socket</span><br><span>  *  \param[in] cli Stream Client to modify</span><br><span style="color: hsl(0, 100%, 40%);">- *  \param[in] timeout Re-connect timeout in seconds */</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] timeout Re-connect timeout in seconds or negative value to disable auto-reconnection */</span><br><span> void</span><br><span> osmo_stream_cli_set_reconnect_timeout(struct osmo_stream_cli *cli, int timeout)</span><br><span> {</span><br><span>@@ -475,7 +476,8 @@</span><br><span>    talloc_free(cli);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Open connection of an Osmocom stream client</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief DEPRECATED: use osmo_stream_cli_set_reconnect_timeout() or osmo_stream_cli_reconnect() instead!</span><br><span style="color: hsl(120, 100%, 40%);">+ * Open connection of an Osmocom stream client</span><br><span>  *  \param[in] cli Stream Client to connect</span><br><span>  *  \param[in] reconect 1 if we should not automatically reconnect</span><br><span>  */</span><br><span>@@ -534,10 +536,44 @@</span><br><span> }</span><br><span> </span><br><span> /*! \brief Open connection of an Osmocom stream client</span><br><span style="color: hsl(120, 100%, 40%);">+ *  By default the client will automatically reconnect after default timeout.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  To disable this, use osmo_stream_cli_set_reconnect_timeout() before calling this function.</span><br><span>  *  \param[in] cli Stream Client to connect */</span><br><span> int osmo_stream_cli_open(struct osmo_stream_cli *cli)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      return osmo_stream_cli_open2(cli, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* we are reconfiguring this socket, close existing first. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((cli->flags & OSMO_STREAM_CLI_F_RECONF) && cli->ofd.fd >= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         osmo_stream_cli_close(cli);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ cli->flags &= ~OSMO_STREAM_CLI_F_RECONF;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ret = osmo_sock_init2(AF_INET, SOCK_STREAM, cli->proto,</span><br><span style="color: hsl(120, 100%, 40%);">+                          cli->local_addr, cli->local_port,</span><br><span style="color: hsl(120, 100%, 40%);">+                       cli->addr, cli->port,</span><br><span style="color: hsl(120, 100%, 40%);">+                           OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (ret < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_stream_cli_reconnect(cli);</span><br><span style="color: hsl(120, 100%, 40%);">+               return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     cli->ofd.fd = ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (cli->flags & OSMO_STREAM_CLI_F_NODELAY) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ret = setsockopt_nodelay(cli->ofd.fd, cli->proto, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (ret < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                       goto error_close_socket;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (osmo_fd_register(&cli->ofd) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                goto error_close_socket;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+error_close_socket:</span><br><span style="color: hsl(120, 100%, 40%);">+      close(ret);</span><br><span style="color: hsl(120, 100%, 40%);">+   cli->ofd.fd = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+  return -EIO;</span><br><span> }</span><br><span> </span><br><span> static void cli_timer_cb(void *data)</span><br><span>@@ -549,7 +585,7 @@</span><br><span>  switch(cli->state) {</span><br><span>      case STREAM_CLI_STATE_CONNECTING:</span><br><span>            cli->ofd.when |= BSC_FD_READ | BSC_FD_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">-         osmo_stream_cli_open2(cli, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+                osmo_stream_cli_open(cli);</span><br><span>           break;</span><br><span>       default:</span><br><span>             break;</span><br><span>diff --git a/tests/stream/stream_test.c b/tests/stream/stream_test.c</span><br><span>index 1a0c555..439ea1a 100644</span><br><span>--- a/tests/stream/stream_test.c</span><br><span>+++ b/tests/stream/stream_test.c</span><br><span>@@ -126,6 +126,76 @@</span><br><span>   return cli;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Without explicit timeout set with osmo_stream_cli_set_reconnect_timeout() default value is used.</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_stream_cli *init_client_reconnection_broken1(struct osmo_stream_cli *cli, bool autoreconnect)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        if (osmo_stream_cli_open2(cli, autoreconnect) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGCLI(cli, "unable to open client\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return cli;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+That's why those those functions result in exact the same output despite inverse use of autoreconnect parameter.</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_stream_cli *init_client_reconnection_broken2(struct osmo_stream_cli *cli, bool autoreconnect)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     if (osmo_stream_cli_open2(cli, !autoreconnect) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGCLI(cli, "unable to open client\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return cli;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Variant below are also equivalent to each other.</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_stream_cli *init_client_reconnection_broken1(struct osmo_stream_cli *cli, bool autoreconnect)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_stream_cli_set_reconnect_timeout(cli, (!autoreconnect) ? 2 : -1);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (osmo_stream_cli_open2(cli, autoreconnect) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGCLI(cli, "unable to open client\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return cli;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_stream_cli *init_client_reconnection_broken2(struct osmo_stream_cli *cli, bool autoreconnect)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_stream_cli_set_reconnect_timeout(cli, (!autoreconnect) ? 2 : -1);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (osmo_stream_cli_open2(cli, !autoreconnect) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGCLI(cli, "unable to open client\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return cli;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+Note: the result differs from normal init_client_reconnection()</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Setting reconnection value explicitly as follows is equivalent to normal init_client_reconnection()</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_stream_cli *init_client_reconnection_broken1(struct osmo_stream_cli *cli, bool autoreconnect)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_stream_cli_set_reconnect_timeout(cli, autoreconnect ? 2 : -1);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (osmo_stream_cli_open2(cli, autoreconnect) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGCLI(cli, "unable to open client\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return cli;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_stream_cli *init_client_reconnection_broken2(struct osmo_stream_cli *cli, bool autoreconnect)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_stream_cli_set_reconnect_timeout(cli, autoreconnect ? 2 : -1);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (osmo_stream_cli_open2(cli, !autoreconnect) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGCLI(cli, "unable to open client\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return cli;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static struct osmo_stream_cli *make_client(void *ctx, const char *host, unsigned port, bool autoreconnect)</span><br><span> {</span><br><span>      struct osmo_stream_cli *cli = osmo_stream_cli_create(ctx);</span><br><span>@@ -141,6 +211,12 @@</span><br><span>    osmo_stream_cli_set_connect_cb(cli, connect_cb_cli);</span><br><span>         osmo_stream_cli_set_read_cb(cli, read_cb_cli);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    /* using</span><br><span style="color: hsl(120, 100%, 40%);">+         return init_client_reconnection_broken1(cli, autoreconnect);</span><br><span style="color: hsl(120, 100%, 40%);">+          or</span><br><span style="color: hsl(120, 100%, 40%);">+    return init_client_reconnection_broken2(cli, autoreconnect);</span><br><span style="color: hsl(120, 100%, 40%);">+          will result in exactly the same output which might or might not be the same as with</span><br><span style="color: hsl(120, 100%, 40%);">+           init_client_reconnection() - see preceeding notes */</span><br><span>      return init_client_reconnection(cli, autoreconnect);</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12845">change 12845</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/12845"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmo-netif </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Id988ed0274b363db049f59cbf6a193727c8c3c8a </div>
<div style="display:none"> Gerrit-Change-Number: 12845 </div>
<div style="display:none"> Gerrit-PatchSet: 8 </div>
<div style="display:none"> Gerrit-Owner: Max <msuraev@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Max <msuraev@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Pau Espin Pedrol <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: osmith <osmith@sysmocom.de> </div>