Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package gensio for openSUSE:Factory checked 
in at 2021-06-09 21:51:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gensio (Old)
 and      /work/SRC/openSUSE:Factory/.gensio.new.32437 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gensio"

Wed Jun  9 21:51:57 2021 rev:11 rq:897966 version:2.2.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/gensio/gensio.changes    2021-05-15 
23:17:30.320421581 +0200
+++ /work/SRC/openSUSE:Factory/.gensio.new.32437/gensio.changes 2021-06-09 
21:52:12.630464947 +0200
@@ -1,0 +2,8 @@
+Sat Jun  5 10:42:39 UTC 2021 - Martin Hauke <mar...@gmx.de>
+
+- Update to version 2.2.7
+  * Fix: multiple connections to UDP sockets not work correctly.
+- Update to version 2.2.6
+  * Mostly small bug fixes.
+
+-------------------------------------------------------------------

Old:
----
  gensio-2.2.5.tar.gz

New:
----
  gensio-2.2.7.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ gensio.spec ++++++
--- /var/tmp/diff_new_pack.ipeRWW/_old  2021-06-09 21:52:13.142465860 +0200
+++ /var/tmp/diff_new_pack.ipeRWW/_new  2021-06-09 21:52:13.146465867 +0200
@@ -25,7 +25,7 @@
 %bcond_with    openipmi
 %endif
 Name:           gensio
-Version:        2.2.5
+Version:        2.2.7
 Release:        0
 Summary:        Library to abstract stream and packet I/O
 # examples/* is licenced under Apache-2.0

++++++ gensio-2.2.5.tar.gz -> gensio-2.2.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gensio-2.2.5/CMakeLists.txt 
new/gensio-2.2.7/CMakeLists.txt
--- old/gensio-2.2.5/CMakeLists.txt     2021-05-11 03:04:32.000000000 +0200
+++ new/gensio-2.2.7/CMakeLists.txt     2021-05-28 21:16:02.000000000 +0200
@@ -1,6 +1,6 @@
 cmake_minimum_required(VERSION 3.10)
 
-project(gensio VERSION 2.2.4)
+project(gensio VERSION 2.2.6)
 set (gensio_VERSION_STRING 
"${gensio_VERSION_MAJOR}.${gensio_VERSION_MINOR}.${gensio_VERSION_PATCH}")
 
 include_directories("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gensio-2.2.5/configure.ac 
new/gensio-2.2.7/configure.ac
--- old/gensio-2.2.5/configure.ac       2021-05-11 03:04:32.000000000 +0200
+++ new/gensio-2.2.7/configure.ac       2021-05-28 21:16:02.000000000 +0200
@@ -1,7 +1,7 @@
-AC_INIT([gensio], [2.2.5], [miny...@acm.org])
+AC_INIT([gensio], [2.2.7], [miny...@acm.org])
 AC_SUBST(gensio_VERSION_MAJOR, 2)
 AC_SUBST(gensio_VERSION_MINOR, 2)
-AC_SUBST(gensio_VERSION_PATCH, 5)
+AC_SUBST(gensio_VERSION_PATCH, 7)
 AC_SUBST(gensio_VERSION_STRING, ${PACKAGE_VERSION})
 AC_CANONICAL_TARGET
 AM_INIT_AUTOMAKE([-Wall])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gensio-2.2.5/lib/gensio_ll_fd.c 
new/gensio-2.2.7/lib/gensio_ll_fd.c
--- old/gensio-2.2.5/lib/gensio_ll_fd.c 2021-05-11 03:04:32.000000000 +0200
+++ new/gensio-2.2.7/lib/gensio_ll_fd.c 2021-05-28 21:16:02.000000000 +0200
@@ -587,7 +587,14 @@
        int err;
 
        err = fdll->ops->check_open(fdll->handler_data, fdll->fd);
-       if (err && fdll->ops->retry_open) {
+       /*
+        * The GE_NOMEM check is strange here, but it really has more
+        * to do with testing.  check_open() is not going to return
+        * GE_NOMEM unless it's an error trigger failure, and we really
+        * want to fail in that case or we will get a "error triggered
+        * but no failure" in the test.
+        */
+       if (err && err != GE_NOMEM && fdll->ops->retry_open) {
            fd_set_state(fdll, FD_IN_OPEN_RETRY);
            fdll->o->clear_fd_handlers(fdll->o, fdll->fd);
        } else {
@@ -722,8 +729,11 @@
     if (fdll->state == FD_IN_OPEN_RETRY) {
        gensio_os_close(fdll->o, &fdll->fd);
        err = fdll->ops->retry_open(fdll->handler_data, &fdll->fd);
-       if (err == GE_INPROGRESS)
+       if (err == GE_INPROGRESS) {
            err = fd_setup_handlers(fdll);
+           if (!err)
+               fd_set_state(fdll, FD_IN_OPEN);
+       }
        if (err) {
            fd_deref(fdll);
            fd_finish_open(fdll, err);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gensio-2.2.5/lib/gensio_net.c 
new/gensio-2.2.7/lib/gensio_net.c
--- old/gensio-2.2.5/lib/gensio_net.c   2021-05-11 03:04:32.000000000 +0200
+++ new/gensio-2.2.7/lib/gensio_net.c   2021-05-28 21:16:02.000000000 +0200
@@ -66,6 +66,7 @@
     int protocol = tdata->istcp ? GENSIO_NET_PROTOCOL_TCP
                                : GENSIO_NET_PROTOCOL_UNIX;
 
+ retry:
     err = gensio_os_socket_open(tdata->o, tdata->ai, protocol, &new_fd);
     if (err)
        goto out;
@@ -76,16 +77,24 @@
     if (err)
        goto out;
 
- retry:
     err = gensio_os_connect(tdata->o, new_fd, tdata->ai);
     if (err == GE_INPROGRESS) {
        *fd = new_fd;
        goto out_return;
     }
 
-    if (err) {
-       if (gensio_addr_next(tdata->ai))
+    /*
+     * The GE_NOMEM check is strange here, but it really has more to
+     * do with testing.  connect() is not going to return GE_NOMEM
+     * unless it's an error trigger failure, and we really want to
+     * fail in that case or we will get a "error triggered but no
+     * failure" in the test.
+     */
+    if (err && err != GE_NOMEM) {
+       if (gensio_addr_next(tdata->ai)) {
+           gensio_os_close(tdata->o, &new_fd);
            goto retry;
+       }
     }
  out:
     if (err) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gensio-2.2.5/lib/gensio_osops.c 
new/gensio-2.2.7/lib/gensio_osops.c
--- old/gensio-2.2.5/lib/gensio_osops.c 2021-05-11 03:04:32.000000000 +0200
+++ new/gensio-2.2.7/lib/gensio_osops.c 2021-05-28 21:16:02.000000000 +0200
@@ -137,6 +137,25 @@
     return 0;
 }
 
+static bool sockaddr_equal(const struct sockaddr *a1, socklen_t l1,
+                          const struct sockaddr *a2, socklen_t l2,
+                          bool compare_ports);
+
+/* Does sa have an equivalent address in the list before this address? */
+static bool
+sockaddr_in_list_b4(struct addrinfo *sa, struct addrinfo *l)
+{
+    for (; l; l = l->ai_next) {
+       if (sa == l)
+           break;
+       if (sockaddr_equal(sa->ai_addr, sa->ai_addrlen,
+                          l->ai_addr, l->ai_addrlen,
+                          true))
+           return true;
+    }
+    return false;
+}
+
 #define ERRHANDLE()                    \
 do {                                                           \
     int err = 0;                                               \
@@ -255,7 +274,7 @@
 }
 
 static struct gensio_addr *
-gensio_addr_make(struct gensio_os_funcs *o, socklen_t size)
+gensio_addr_make(struct gensio_os_funcs *o, socklen_t size, bool do_refcount)
 {
     struct gensio_addr *addr = o->zalloc(o, sizeof(*addr));
     struct addrinfo *ai = NULL;
@@ -264,19 +283,22 @@
        return NULL;
 
 #if HAVE_GCC_ATOMICS
-    addr->refcount = o->zalloc(o, sizeof(*addr->refcount));
-    if (!addr->refcount) {
-       o->free(o, addr);
-       return NULL;
+    if (do_refcount) {
+       addr->refcount = o->zalloc(o, sizeof(*addr->refcount));
+       if (!addr->refcount) {
+           o->free(o, addr);
+           return NULL;
+       }
+       *addr->refcount = 1;
     }
-    *addr->refcount = 1;
 #endif
 
     if (size > 0) {
        ai = o->zalloc(o, sizeof(*ai));
        if (!ai) {
 #if HAVE_GCC_ATOMICS
-           o->free(o, addr->refcount);
+           if (addr->refcount)
+               o->free(o, addr->refcount);
 #endif
            o->free(o, addr);
            return NULL;
@@ -285,7 +307,8 @@
        ai->ai_addr = o->zalloc(o, size);
        if (!ai->ai_addr) {
 #if HAVE_GCC_ATOMICS
-           o->free(o, addr->refcount);
+           if (addr->refcount)
+               o->free(o, addr->refcount);
 #endif
            o->free(o, addr);
            o->free(o, ai);
@@ -349,7 +372,7 @@
        return GE_INVAL;
     }
 
-    a = gensio_addr_make(o, slen);
+    a = gensio_addr_make(o, slen, true);
     if (!a)
        return GE_NOMEM;
     a->a->ai_family = s->sa_family;
@@ -362,7 +385,12 @@
 struct gensio_addr *
 gensio_addr_alloc_recvfrom(struct gensio_os_funcs *o)
 {
-    return gensio_addr_make(o, sizeof(struct sockaddr_storage));
+    /*
+     * Addresses used for recvfrom cannot be duplicated with refcounts
+     * because the storage is reused.  So allocate them without a
+     * refcount to mark them to always do a full replication.
+     */
+    return gensio_addr_make(o, sizeof(struct sockaddr_storage), false);
 }
 
 int
@@ -408,7 +436,7 @@
        return GE_NOMEM;
 
     if (raddr) {
-       addr = gensio_addr_make(o, sizeof(struct sockaddr_storage));
+       addr = gensio_addr_make(o, sizeof(struct sockaddr_storage), true);
        if (!addr)
            return GE_NOMEM;
        sa = addr->curr->ai_addr;
@@ -500,7 +528,7 @@
                           void *data, unsigned int opensock_flags,
                           struct opensocks **rfds, unsigned int *rnr_fds)
 {
-    struct addrinfo *ai;
+    struct addrinfo *ai, *rp;
     unsigned int i;
     int family = AF_INET6;
     int rv = 0;
@@ -510,20 +538,30 @@
 
     memset(&scaninfo, 0, sizeof(scaninfo));
 
+    ai = addr->a;
  retry:
-    for (ai = addr->a; ai; ai = ai->ai_next) {
+    for (rp = ai; rp; rp = rp->ai_next) {
        unsigned int port;
 
-       if (family != ai->ai_family)
+       if (family != rp->ai_family)
            continue;
+       /*
+        * getaddrinfo() will return the same address twice in the
+        * list if ::1 and 127.0.0.1 are both set for localhost in
+        * /etc/hosts.  So the second open attempt will fail if we
+        * don't ignore this.  In general, it's probably better to
+        * ignore duplicates in this function, anyway.
+        */
+       if (sockaddr_in_list_b4(rp, ai))
+            continue;
 
-       rv = sockaddr_get_port(ai->ai_addr, &port);
+       rv = sockaddr_get_port(rp->ai_addr, &port);
        if (rv)
            goto out_err;
 
        for (i = 0; i < nr_fds; i++) {
            if (port == fds[i].port && (fds[i].family == family)) {
-               if (sctp_bindx(fds[i].fd, ai->ai_addr, 1,
+               if (sctp_bindx(fds[i].fd, rp->ai_addr, 1,
                               SCTP_BINDX_ADD_ADDR)) {
                    rv = gensio_os_err_to_err(o, errno);
                    goto out_err;
@@ -543,9 +581,9 @@
        if (fds)
            memcpy(tfds, fds, sizeof(*tfds) * i);
 
-       rv = gensio_setup_listen_socket(o, true, ai->ai_family,
-                                       SOCK_STREAM, IPPROTO_SCTP, ai->ai_flags,
-                                       ai->ai_addr, ai->ai_addrlen,
+       rv = gensio_setup_listen_socket(o, true, rp->ai_family,
+                                       SOCK_STREAM, IPPROTO_SCTP, rp->ai_flags,
+                                       rp->ai_addr, rp->ai_addrlen,
                                        readhndlr, NULL, data,
                                        fd_handler_cleared,
                                        setup_socket, opensock_flags,
@@ -554,8 +592,8 @@
            o->free(o, tfds);
            goto out_err;
        }
-       tfds[i].family = ai->ai_family;
-       tfds[i].flags = ai->ai_flags;
+       tfds[i].family = rp->ai_family;
+       tfds[i].flags = rp->ai_flags;
        if (fds)
            o->free(o, fds);
        fds = tfds;
@@ -695,29 +733,15 @@
     struct addrinfo *ai;
     char *saddrs, *s;
     unsigned int slen = 0, i, memlen = 0;
-    int ipv6_only = -1;
+    int ipv6_only = 1;
 
     for (ai = addrs->a; ai; ai = ai->ai_next) {
        unsigned int len;
 
        if (ai->ai_addr->sa_family == AF_INET6) {
            len = sizeof(struct sockaddr_in6);
-           if (ai->ai_flags & AI_V4MAPPED) {
-               if (ipv6_only == 1)
-                   /* Can't mix IPV6-only with IPV4 mapped. */
-                   return GE_INVAL;
-               ipv6_only = 0;
-           } else if (ipv6_only == 0) {
-               /* Can't mix IPV6-only with IPV4 mapped. */
-               return GE_INVAL;
-           } else {
-               ipv6_only = 1;
-           }
        } else if (ai->ai_addr->sa_family == AF_INET) {
            len = sizeof(struct sockaddr_in);
-           if (ipv6_only == 1)
-               /* Can't mix IPV6-only with IPV4. */
-               return GE_INVAL;
            ipv6_only = 0;
        } else {
            return GE_INVAL;
@@ -844,7 +868,7 @@
     char *d;
     int rv;
 
-    addr = gensio_addr_make(o, 0);
+    addr = gensio_addr_make(o, 0, true);
     if (!addr)
        return GE_NOMEM;
 
@@ -983,9 +1007,11 @@
                      const struct gensio_addr *addr, int protocol,
                      int *fd)
 {
-    int sockproto, socktype;
+    int sockproto, socktype, family;
     int newfd;
 
+    family = addr->curr->ai_family;
+
     if (do_errtrig())
        return GE_NOMEM;
 
@@ -1005,6 +1031,13 @@
     case GENSIO_NET_PROTOCOL_SCTP:
        sockproto = IPPROTO_SCTP;
        socktype = SOCK_STREAM;
+#ifdef AF_INET6
+       /*
+        * For SCTP, always use AF_INET6 if available.  sctp_connectx()
+        * can use ipv4 addresses, too, on an AF_INET6 socket.
+        */
+       family = AF_INET6;
+#endif
        break;
 #endif
 
@@ -1012,7 +1045,7 @@
        return GE_INVAL;
     }
 
-    newfd = socket(addr->a->ai_family, socktype, sockproto);
+    newfd = socket(family, socktype, sockproto);
     if (newfd == -1)
        return gensio_os_err_to_err(o, errno);
     *fd = newfd;
@@ -1058,11 +1091,12 @@
     }
 
     if (bindaddr) {
-       struct addrinfo *ai = bindaddr->a;
+       struct addrinfo *ai;
 
        switch (protocol) {
 #if HAVE_LIBSCTP
        case GENSIO_NET_PROTOCOL_SCTP:
+           ai = bindaddr->a;
            while (ai) {
                if (sctp_bindx(fd, ai->ai_addr, 1, SCTP_BINDX_ADD_ADDR) == -1)
                    return gensio_os_err_to_err(o, errno);
@@ -1074,6 +1108,7 @@
        case GENSIO_NET_PROTOCOL_TCP:
        case GENSIO_NET_PROTOCOL_UDP:
        case GENSIO_NET_PROTOCOL_UNIX:
+           ai = bindaddr->curr;
            if (bind(fd, ai->ai_addr, ai->ai_addrlen) == -1)
                return gensio_os_err_to_err(o, errno);
            break;
@@ -1309,7 +1344,7 @@
     if (do_errtrig())
        return GE_NOMEM;
 
-    addr = gensio_addr_make(o, sizeof(struct sockaddr_storage));
+    addr = gensio_addr_make(o, sizeof(struct sockaddr_storage), true);
     if (!addr)
        return GE_NOMEM;
 
@@ -1461,6 +1496,15 @@
     for (rp = ai->a; rp != NULL; rp = rp->ai_next) {
        if (family != rp->ai_family)
            continue;
+       /*
+        * getaddrinfo() will return the same address twice in the
+        * list if ::1 and 127.0.0.1 are both set for localhost in
+        * /etc/hosts.  So the second open attempt will fail if we
+        * don't ignore this.  In general, it's probably better to
+        * ignore duplicates in this function, anyway.
+        */
+       if (sockaddr_in_list_b4(rp, ai->a))
+            continue;
 
        rv = gensio_setup_listen_socket(o, rp->ai_socktype == SOCK_STREAM,
                                        rp->ai_family, rp->ai_socktype,
@@ -1950,7 +1994,7 @@
     if (!strtok_buffer)
        return GE_NOMEM;
 
-    addr = gensio_addr_make(o, 0);
+    addr = gensio_addr_make(o, 0, true);
     if (!addr) {
        o->free(o, strtok_buffer);
        return GE_NOMEM;
@@ -1959,7 +2003,7 @@
     ip = strtok_r(strtok_buffer, ",", &strtok_data);
     while (ip) {
        int family = ifamily, rflags = 0;
-       bool notype = false;
+       bool notype = false, gotaddr = false;
 
        if (strcmp(ip, "ipv4") == 0) {
            if (family != AF_UNSPEC && family != AF_INET) {
@@ -2010,9 +2054,9 @@
             * host).  If the user does not specify an IP address, use
             * AF_INET6 and AI_V4MAPPED and it works fine.  If the
             * user specifies an IP address, pull the V6 addresses
-            * then the V4 addresses.  But only for listen sockets,
-            * connect sockets can only connect to one address (or one
-            * address type for SCTP).
+            * then the V4 addresses.  Do this for TCP connect
+            * sockets, too, as the connection will be tried on each
+            * address.
             */
            if (family == AF_UNSPEC) {
                notype = true;
@@ -2066,9 +2110,16 @@
                goto redo_getaddrinfo;
            }
 #endif
+           if (gotaddr) {
+               /* We got some address earlier, go with it. */
+               rv = 0;
+               goto ignore_getaddr_error;
+           }
+ 
            rv = GE_INVAL;
            goto out_err;
        }
+       gotaddr = true;
 
        /*
         * If a port was/was not set, this must be consistent for all
@@ -2110,14 +2161,13 @@
                goto out_err;
        }
 #ifdef AF_INET6
-       if (listen && ip && notype && ifamily == AF_UNSPEC &&
-               family == AF_INET6) {
+       if (ip && notype && ifamily == AF_UNSPEC && family == AF_INET6) {
            /* See comments above on why this is done.  Yes, it's strange. */
            family = AF_INET;
            goto redo_getaddrinfo;
        }
 #endif
-
+    ignore_getaddr_error:
        ip = strtok_r(NULL, ",", &strtok_data);
        first = false;
     }
@@ -2157,7 +2207,7 @@
     if (len >= sizeof(saddr->sun_path) - 1)
        return GE_TOOBIG;
 
-    addr = gensio_addr_make(o, sizeof(socklen_t) + len + 1);
+    addr = gensio_addr_make(o, sizeof(socklen_t) + len + 1, true);
     if (!addr)
        return GE_NOMEM;
 
@@ -2452,21 +2502,34 @@
     addr->o = o;
 
 #if HAVE_GCC_ATOMICS
-    addr->refcount = iaddr->refcount;
-    addr->a = iaddr->a;
-    addr->is_getaddrinfo = iaddr->is_getaddrinfo;
-    __atomic_add_fetch(addr->refcount, 1, __ATOMIC_SEQ_CST);
-#else
-    do {
-       int rv;
+    if (iaddr->refcount) {
+       addr->refcount = iaddr->refcount;
+       addr->a = iaddr->a;
+       addr->is_getaddrinfo = iaddr->is_getaddrinfo;
+       __atomic_add_fetch(addr->refcount, 1, __ATOMIC_SEQ_CST);
+    } else {
+#endif
+       do {
+           int rv;
 
-       rv = addrinfo_list_dup(o, iaddr->a, &addr->a, NULL);
-       if (rv) {
-           addrinfo_list_free(o, addr->a);
-           o->free(o, addr);
-           return NULL;
-       }
-    } while(false);
+           rv = addrinfo_list_dup(o, iaddr->a, &addr->a, NULL);
+           if (rv) {
+               addrinfo_list_free(o, addr->a);
+               o->free(o, addr);
+               return NULL;
+           }
+#if HAVE_GCC_ATOMICS
+           addr->refcount = o->zalloc(o, sizeof(*addr->refcount));
+           if (!addr->refcount) {
+               addrinfo_list_free(o, addr->a);
+               o->free(o, addr);
+               return NULL;
+           }
+           *addr->refcount = 1;
+#endif
+       } while(false);
+#if HAVE_GCC_ATOMICS
+    }
 #endif
     addr->curr = addr->a;
 
@@ -2482,7 +2545,7 @@
     struct addrinfo *aip = NULL;
     int rv;
 
-    addr = gensio_addr_make(o, 0);
+    addr = gensio_addr_make(o, 0, true);
     if (!addr)
        return NULL;
 
@@ -2555,11 +2618,13 @@
 
     o = addr->o;
 #if HAVE_GCC_ATOMICS
-    if (__atomic_sub_fetch(addr->refcount, 1, __ATOMIC_SEQ_CST) != 0) {
-       o->free(o, addr);
-       return;
+    if (addr->refcount) {
+       if (__atomic_sub_fetch(addr->refcount, 1, __ATOMIC_SEQ_CST) != 0) {
+           o->free(o, addr);
+           return;
+       }
+       o->free(o, addr->refcount);
     }
-    o->free(o, addr->refcount);
 #endif
     if (addr->a) {
        if (addr->is_getaddrinfo)

Reply via email to