<p>lynxis lazus has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/19143">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">socket.c: introduce osmo_sock_init3 & osmo_sock_init3_ofd<br><br>osmo_sock_init3() takes osmo_sockaddr* as local and remote endpoints<br>to setup a socket.<br><br>Change-Id: I1eece543e3241ef0e095eb63bb831f7c15a16794<br>---<br>M include/osmocom/core/socket.h<br>M src/socket.c<br>2 files changed, 124 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/43/19143/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h</span><br><span>index bc60dfc..6bfcc4c 100644</span><br><span>--- a/include/osmocom/core/socket.h</span><br><span>+++ b/include/osmocom/core/socket.h</span><br><span>@@ -66,6 +66,15 @@</span><br><span>                      const char *local_host, uint16_t local_port,</span><br><span>                         const char *remote_host, uint16_t remote_port, unsigned int flags);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sock_init3(uint16_t type, uint8_t proto,</span><br><span style="color: hsl(120, 100%, 40%);">+                const struct osmo_sockaddr *local,</span><br><span style="color: hsl(120, 100%, 40%);">+                    const struct osmo_sockaddr *remote,</span><br><span style="color: hsl(120, 100%, 40%);">+                   unsigned int flags);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sock_init3_ofd(struct osmo_fd *ofd, int type, int proto,</span><br><span style="color: hsl(120, 100%, 40%);">+                 const struct osmo_sockaddr *local,</span><br><span style="color: hsl(120, 100%, 40%);">+                    const struct osmo_sockaddr *remote, unsigned int flags);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type,</span><br><span>                    uint8_t proto, unsigned int flags);</span><br><span> </span><br><span>diff --git a/src/socket.c b/src/socket.c</span><br><span>index 359e24d..c7fd28b 100644</span><br><span>--- a/src/socket.c</span><br><span>+++ b/src/socket.c</span><br><span>@@ -34,6 +34,7 @@</span><br><span> #include <osmocom/core/logging.h></span><br><span> #include <osmocom/core/select.h></span><br><span> #include <osmocom/core/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/sockaddr_str.h></span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/core/utils.h></span><br><span> </span><br><span>@@ -153,6 +154,28 @@</span><br><span>    return sfd;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int socket_helper_sa(const struct osmo_sockaddr *addr, uint16_t type, uint8_t proto, unsigned int flags)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      int sfd, on = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    sfd = socket(addr->u.sa.sa_family, type, proto);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (sfd == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DLGLOBAL, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+                    "unable to create socket: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+          return sfd;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (flags & OSMO_SOCK_F_NONBLOCK) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   LOGP(DLGLOBAL, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+                            "cannot set this socket unblocking: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                          strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                     close(sfd);</span><br><span style="color: hsl(120, 100%, 40%);">+                   sfd = -EINVAL;</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 sfd;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #ifdef HAVE_LIBSCTP</span><br><span> /* Fill buf with a string representation of the address set, in the form:</span><br><span>  * buf_len == 0: "()"</span><br><span>@@ -422,6 +445,91 @@</span><br><span>       return sfd;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define OSMO_SOCKADDR_TO_STR(sockaddr) \</span><br><span style="color: hsl(120, 100%, 40%);">+        struct osmo_sockaddr_str sastr; \</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = osmo_sockaddr_str_from_sockaddr(&sastr, &sockaddr->u.sas); \</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rc) \</span><br><span style="color: hsl(120, 100%, 40%);">+             strcpy(sastr.ip, "Invalid IP")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sock_init3(uint16_t type, uint8_t proto,</span><br><span style="color: hsl(120, 100%, 40%);">+             const struct osmo_sockaddr *local,</span><br><span style="color: hsl(120, 100%, 40%);">+                    const struct osmo_sockaddr *remote,</span><br><span style="color: hsl(120, 100%, 40%);">+                   unsigned int flags)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int sfd = -1, rc, on = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGP(DLGLOBAL, LOGL_ERROR, "invalid: you have to specify either "</span><br><span style="color: hsl(120, 100%, 40%);">+                   "BIND or CONNECT flags\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return -EINVAL;</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%);">+   /* figure out local side of socket */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (flags & OSMO_SOCK_F_BIND) {</span><br><span style="color: hsl(120, 100%, 40%);">+           sfd = socket_helper_sa(local, type, proto, flags);</span><br><span style="color: hsl(120, 100%, 40%);">+            if (sfd < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     OSMO_SOCKADDR_TO_STR(local);</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOGP(DLGLOBAL, LOGL_ERROR, "no suitable local addr found for: %s:%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                             sastr.ip, sastr.port);</span><br><span style="color: hsl(120, 100%, 40%);">+                        return -ENODEV;</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 (proto != IPPROTO_UDP || flags & OSMO_SOCK_F_UDP_REUSEADDR) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  rc = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR,</span><br><span style="color: hsl(120, 100%, 40%);">+                                        &on, sizeof(on));</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              OSMO_SOCKADDR_TO_STR(local);</span><br><span style="color: hsl(120, 100%, 40%);">+                          LOGP(DLGLOBAL, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 "cannot setsockopt socket:"</span><br><span style="color: hsl(120, 100%, 40%);">+                                 " %s:%u: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                     sastr.ip, sastr.port,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                                close(sfd);</span><br><span style="color: hsl(120, 100%, 40%);">+                           return rc;</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 style="color: hsl(120, 100%, 40%);">+           if (bind(sfd, &local->u.sa, sizeof(struct osmo_sockaddr)) == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     OSMO_SOCKADDR_TO_STR(local);</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOGP(DLGLOBAL, LOGL_ERROR, "unable to bind socket: %s:%u: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                         sastr.ip, sastr.port, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                  close(sfd);</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 style="color: hsl(120, 100%, 40%);">+   /* Reached this point, if OSMO_SOCK_F_BIND then sfd is valid (>=0) or it</span><br><span style="color: hsl(120, 100%, 40%);">+      was already closed and func returned. If OSMO_SOCK_F_BIND is not</span><br><span style="color: hsl(120, 100%, 40%);">+      set, then sfd = -1 */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* figure out remote side of socket */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (flags & OSMO_SOCK_F_CONNECT) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (sfd < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     sfd = socket_helper_sa(remote, type, proto, flags);</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (sfd < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                             return sfd;</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 style="color: hsl(120, 100%, 40%);">+           rc = connect(sfd, &remote->u.sa, sizeof(struct osmo_sockaddr));</span><br><span style="color: hsl(120, 100%, 40%);">+                if (rc != 0 && errno != EINPROGRESS) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        OSMO_SOCKADDR_TO_STR(local);</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOGP(DLGLOBAL, LOGL_ERROR, "unable to connect socket: %s:%u: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      sastr.ip, sastr.port, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                  close(sfd);</span><br><span style="color: hsl(120, 100%, 40%);">+                   return rc;</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 style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_sock_init_tail(sfd, type, flags);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              close(sfd);</span><br><span style="color: hsl(120, 100%, 40%);">+           sfd = -1;</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 sfd;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #ifdef HAVE_LIBSCTP</span><br><span> </span><br><span> </span><br><span>@@ -809,6 +917,13 @@</span><br><span>                                       local_port, remote_host, remote_port, flags));</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sock_init3_ofd(struct osmo_fd *ofd, int type, int proto,</span><br><span style="color: hsl(120, 100%, 40%);">+                    const struct osmo_sockaddr *local,</span><br><span style="color: hsl(120, 100%, 40%);">+                    const struct osmo_sockaddr *remote, unsigned int flags)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    return osmo_fd_init_ofd(ofd, osmo_sock_init3(type, proto, local, remote, flags));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Initialize a socket and fill \ref sockaddr</span><br><span>  *  \param[out] ss socket address (will be filled in)</span><br><span>  *  \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/19143">change 19143</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/c/libosmocore/+/19143"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I1eece543e3241ef0e095eb63bb831f7c15a16794 </div>
<div style="display:none"> Gerrit-Change-Number: 19143 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: lynxis lazus <lynxis@fe80.eu> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>