Stop raising ERR_R_MALLOC_FAILURE in most places
[openssl.git] / crypto / bio / bio_sock.c
index b827c5b902b19a4ab46cd337617b43d32f9e9993..7aa7bdc65ee90d579655a6c9fa9c6e20994b1806 100644 (file)
@@ -35,6 +35,8 @@ static int wsa_init_done = 0;
 #  include <unistd.h>
 #  if defined __VMS
 #   include <sys/socket.h>
+#  elif defined _HPUX_SOURCE
+#   include <sys/time.h>
 #  else
 #   include <sys/select.h>
 #  endif
@@ -128,6 +130,11 @@ struct hostent *BIO_gethostbyname(const char *name)
 }
 # endif
 
+# ifdef BIO_HAVE_WSAMSG
+LPFN_WSARECVMSG bio_WSARecvMsg;
+LPFN_WSASENDMSG bio_WSASendMsg;
+# endif
+
 int BIO_sock_init(void)
 {
 # ifdef OPENSSL_SYS_WINDOWS
@@ -148,6 +155,39 @@ int BIO_sock_init(void)
             ERR_raise(ERR_LIB_BIO, BIO_R_WSASTARTUP);
             return -1;
         }
+
+        /*
+         * On Windows, some socket functions are not exposed as a prototype.
+         * Instead, their function pointers must be loaded via this elaborate
+         * process...
+         */
+#  ifdef BIO_HAVE_WSAMSG
+        {
+            GUID id_WSARecvMsg = WSAID_WSARECVMSG;
+            GUID id_WSASendMsg = WSAID_WSASENDMSG;
+            DWORD len_out = 0;
+            SOCKET s;
+
+            s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+            if (s != INVALID_SOCKET) {
+                if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
+                             &id_WSARecvMsg, sizeof(id_WSARecvMsg),
+                             &bio_WSARecvMsg, sizeof(bio_WSARecvMsg),
+                             &len_out, NULL, NULL) != 0
+                    || len_out != sizeof(bio_WSARecvMsg))
+                    bio_WSARecvMsg = NULL;
+
+                if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
+                             &id_WSASendMsg, sizeof(id_WSASendMsg),
+                             &bio_WSASendMsg, sizeof(bio_WSASendMsg),
+                             &len_out, NULL, NULL) != 0
+                    || len_out != sizeof(bio_WSASendMsg))
+                    bio_WSASendMsg = NULL;
+
+                closesocket(s);
+            }
+        }
+#  endif
     }
 # endif                         /* OPENSSL_SYS_WINDOWS */
 # ifdef WATT32
@@ -265,13 +305,14 @@ int BIO_accept(int sock, char **ip_port)
     if (ip_port != NULL) {
         char *host = BIO_ADDR_hostname_string(&res, 1);
         char *port = BIO_ADDR_service_string(&res, 1);
-        if (host != NULL && port != NULL)
+        if (host != NULL && port != NULL) {
             *ip_port = OPENSSL_zalloc(strlen(host) + strlen(port) + 2);
-        else
+        } else {
             *ip_port = NULL;
+            ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
+        }
 
         if (*ip_port == NULL) {
-            ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
             BIO_closesocket(ret);
             ret = (int)INVALID_SOCKET;
         } else {
@@ -400,7 +441,7 @@ int BIO_socket_wait(int fd, int for_read, time_t max_time)
         return 1;
 
     now = time(NULL);
-    if (max_time <= now)
+    if (max_time < now)
         return 0;
 
     FD_ZERO(&confds);