Deprecate SYSerr, add new FUNCerr macro
[openssl.git] / crypto / bio / b_sock2.c
index f62c07806c78aa804c370afb1cf02d9a25853a6f..ee269513c6062b48f5e4d1326b093d59728a01ed 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-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
@@ -46,7 +46,7 @@ int BIO_socket(int domain, int socktype, int protocol, int options)
 
     sock = socket(domain, socktype, protocol);
     if (sock == -1) {
-        SYSerr(SYS_F_SOCKET, get_last_socket_error());
+        FUNCerr("socket", get_last_socket_error());
         BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
         return INVALID_SOCKET;
     }
@@ -89,7 +89,7 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options)
     if (options & BIO_SOCK_KEEPALIVE) {
         if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
                        (const void *)&on, sizeof(on)) != 0) {
-            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            FUNCerr("setsockopt", get_last_socket_error());
             BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_KEEPALIVE);
             return 0;
         }
@@ -98,7 +98,7 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options)
     if (options & BIO_SOCK_NODELAY) {
         if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
                        (const void *)&on, sizeof(on)) != 0) {
-            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            FUNCerr("setsockopt", get_last_socket_error());
             BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_NODELAY);
             return 0;
         }
@@ -107,7 +107,7 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options)
     if (connect(sock, BIO_ADDR_sockaddr(addr),
                 BIO_ADDR_sockaddr_size(addr)) == -1) {
         if (!BIO_sock_should_retry(-1)) {
-            SYSerr(SYS_F_CONNECT, get_last_socket_error());
+            FUNCerr("connect", get_last_socket_error());
             BIOerr(BIO_F_BIO_CONNECT, BIO_R_CONNECT_ERROR);
         }
         return 0;
@@ -115,6 +115,57 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options)
     return 1;
 }
 
+/*-
+ * BIO_bind - bind socket to address
+ * @sock: the socket to set
+ * @addr: local address to bind to
+ * @options: BIO socket options
+ *
+ * Binds to the address using the given socket and options.
+ *
+ * Options can be a combination of the following:
+ * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
+ *   for a recently closed port.
+ *
+ * When restarting the program it could be that the port is still in use.  If
+ * you set to BIO_SOCK_REUSEADDR option it will try to reuse the port anyway.
+ * It's recommended that you use this.
+ */
+int BIO_bind(int sock, const BIO_ADDR *addr, int options)
+{
+# ifndef OPENSSL_SYS_WINDOWS
+    int on = 1;
+# endif
+
+    if (sock == -1) {
+        BIOerr(BIO_F_BIO_BIND, BIO_R_INVALID_SOCKET);
+        return 0;
+    }
+
+# ifndef OPENSSL_SYS_WINDOWS
+    /*
+     * SO_REUSEADDR has different behavior on Windows than on
+     * other operating systems, don't set it there.
+     */
+    if (options & BIO_SOCK_REUSEADDR) {
+        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+                       (const void *)&on, sizeof(on)) != 0) {
+            FUNCerr("setsockopt", get_last_socket_error());
+            BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_REUSEADDR);
+            return 0;
+        }
+    }
+# endif
+
+    if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) {
+        FUNCerr("bind", get_last_socket_error());
+        BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_BIND_SOCKET);
+        return 0;
+    }
+
+    return 1;
+}
+
 /*-
  * BIO_listen - Creates a listen socket
  * @sock: the socket to listen with
@@ -166,7 +217,7 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options)
     if (getsockopt(sock, SOL_SOCKET, SO_TYPE,
                    (void *)&socktype, &socktype_len) != 0
         || socktype_len != sizeof(socktype)) {
-        SYSerr(SYS_F_GETSOCKOPT, get_last_socket_error());
+        FUNCerr("getsockopt", get_last_socket_error());
         BIOerr(BIO_F_BIO_LISTEN, BIO_R_GETTING_SOCKTYPE);
         return 0;
     }
@@ -174,25 +225,10 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options)
     if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
         return 0;
 
-# ifndef OPENSSL_SYS_WINDOWS
-    /*
-     * SO_REUSEADDR has different behavior on Windows than on
-     * other operating systems, don't set it there.
-     */
-    if (options & BIO_SOCK_REUSEADDR) {
-        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
-                       (const void *)&on, sizeof(on)) != 0) {
-            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
-            BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_REUSEADDR);
-            return 0;
-        }
-    }
-# endif
-
     if (options & BIO_SOCK_KEEPALIVE) {
         if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
                        (const void *)&on, sizeof(on)) != 0) {
-            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            FUNCerr("setsockopt", get_last_socket_error());
             BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_KEEPALIVE);
             return 0;
         }
@@ -201,7 +237,7 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options)
     if (options & BIO_SOCK_NODELAY) {
         if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
                        (const void *)&on, sizeof(on)) != 0) {
-            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            FUNCerr("setsockopt", get_last_socket_error());
             BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY);
             return 0;
         }
@@ -216,21 +252,18 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options)
         on = options & BIO_SOCK_V6_ONLY ? 1 : 0;
         if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
                        (const void *)&on, sizeof(on)) != 0) {
-            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            FUNCerr("setsockopt", get_last_socket_error());
             BIOerr(BIO_F_BIO_LISTEN, BIO_R_LISTEN_V6_ONLY);
             return 0;
         }
     }
 # endif
 
-    if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) {
-        SYSerr(SYS_F_BIND, get_last_socket_error());
-        BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_BIND_SOCKET);
+    if (!BIO_bind(sock, addr, options))
         return 0;
-    }
 
     if (socktype != SOCK_DGRAM && listen(sock, MAX_LISTEN) == -1) {
-        SYSerr(SYS_F_LISTEN, get_last_socket_error());
+        FUNCerr("listen", get_last_socket_error());
         BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_LISTEN_SOCKET);
         return 0;
     }
@@ -257,7 +290,7 @@ int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options)
                            BIO_ADDR_sockaddr_noconst(addr), &len);
     if (accepted_sock == -1) {
         if (!BIO_sock_should_retry(accepted_sock)) {
-            SYSerr(SYS_F_ACCEPT, get_last_socket_error());
+            FUNCerr("accept", get_last_socket_error());
             BIOerr(BIO_F_BIO_ACCEPT_EX, BIO_R_ACCEPT_ERROR);
         }
         return INVALID_SOCKET;