BIO_do_accept: correct error return value
[openssl.git] / crypto / bio / bss_acpt.c
index e426ecd7fd7efd628e01415661677c22a56d7a47..d5b29ecf9ea5396fc2c57420982a76b0fc8b5018 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
- * Licensed under the OpenSSL license (the "License").  You may not use
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
@@ -9,7 +9,7 @@
 
 #include <stdio.h>
 #include <errno.h>
-#include "bio_lcl.h"
+#include "bio_local.h"
 
 #ifndef OPENSSL_NO_SOCK
 
@@ -92,8 +92,10 @@ static BIO_ACCEPT *BIO_ACCEPT_new(void)
 {
     BIO_ACCEPT *ret;
 
-    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
+        BIOerr(BIO_F_BIO_ACCEPT_NEW, ERR_R_MALLOC_FAILURE);
         return NULL;
+    }
     ret->accept_family = BIO_FAMILY_IPANY;
     ret->accept_sock = (int)INVALID_SOCKET;
     return ret;
@@ -103,7 +105,6 @@ static void BIO_ACCEPT_free(BIO_ACCEPT *a)
 {
     if (a == NULL)
         return;
-
     OPENSSL_free(a->param_addr);
     OPENSSL_free(a->param_serv);
     BIO_ADDRINFO_free(a->addr_first);
@@ -221,20 +222,20 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
             break;
 
         case ACPT_S_CREATE_SOCKET:
-            ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
-                             BIO_ADDRINFO_socktype(c->addr_iter),
-                             BIO_ADDRINFO_protocol(c->addr_iter), 0);
-            if (ret == (int)INVALID_SOCKET) {
-                SYSerr(SYS_F_SOCKET, get_last_socket_error());
-                ERR_add_error_data(4,
-                                   "hostname=", c->param_addr,
-                                   " service=", c->param_serv);
+            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) {
+                ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+                               "calling socket(%s, %s)",
+                                c->param_addr, c->param_serv);
                 BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
                 goto exit_loop;
             }
-            c->accept_sock = ret;
-            b->num = ret;
+            c->accept_sock = s;
+            b->num = s;
             c->state = ACPT_S_LISTEN;
+            s = -1;
             break;
 
         case ACPT_S_LISTEN:
@@ -275,6 +276,11 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
             BIO_clear_retry_flags(b);
             b->retry_reason = 0;
 
+            OPENSSL_free(c->cache_peer_name);
+            c->cache_peer_name = NULL;
+            OPENSSL_free(c->cache_peer_serv);
+            c->cache_peer_serv = NULL;
+
             s = BIO_accept_ex(c->accept_sock, &c->cache_peer_addr,
                               c->accepted_mode);
 
@@ -427,7 +433,7 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
                 b->init = 1;
             } else if (num == 1) {
                 OPENSSL_free(data->param_serv);
-                data->param_serv = BUF_strdup(ptr);
+                data->param_serv = OPENSSL_strdup(ptr);
                 b->init = 1;
             } else if (num == 2) {
                 data->bind_mode |= BIO_SOCK_NONBLOCK;
@@ -521,7 +527,12 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
         break;
     case BIO_CTRL_DUP:
         break;
-
+    case BIO_CTRL_EOF:
+        if (b->next_bio == NULL)
+            ret = 0;
+        else
+            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        break;
     default:
         ret = 0;
         break;