BIO acpt_state(): Allow retrying addresses (e.g., using IPv6 vs. IPv4) on creating...
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Tue, 25 May 2021 06:43:59 +0000 (08:43 +0200)
committerDr. David von Oheimb <dev@ddvo.net>
Sat, 29 May 2021 05:47:03 +0000 (07:47 +0200)
Fixes #15386

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15417)

crypto/bio/bss_acpt.c

index aff92223af89791e44d14b2e4aa06065b0df6b33..834c2ffef1a6df780e67b1f876b91edc1c84ffa6 100644 (file)
@@ -216,18 +216,24 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
                 ERR_raise(ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING);
                 goto exit_loop;
             }
-            /* We're currently not iterating, but set this as preparation
-             * for possible future development in that regard
-             */
             c->addr_iter = c->addr_first;
             c->state = ACPT_S_CREATE_SOCKET;
             break;
 
         case ACPT_S_CREATE_SOCKET:
+            ERR_set_mark();
             s = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
                            BIO_ADDRINFO_socktype(c->addr_iter),
                            BIO_ADDRINFO_protocol(c->addr_iter), 0);
             if (s == (int)INVALID_SOCKET) {
+                if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) != NULL) {
+                    /*
+                     * if there are more addresses to try, do that first
+                     */
+                    ERR_pop_to_mark();
+                    break;
+                }
+                ERR_clear_last_mark();
                 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
                                "calling socket(%s, %s)",
                                 c->param_addr, c->param_serv);