make update
[openssl.git] / crypto / bio / b_addr.c
index f1ff5fe37c2a7f7a35428be02b3a683034b6c335..20ef8ec02da3b9af97134c6e631884f8967fab90 100644 (file)
@@ -58,6 +58,7 @@
 
 #include <openssl/err.h>
 #include <openssl/buffer.h>
+#include <ctype.h>
 
 /*
  * Throughout this file and bio_lcl.h, the existence of the macro
@@ -75,7 +76,8 @@
 
 BIO_ADDR *BIO_ADDR_new(void)
 {
-    BIO_ADDR *ret = (BIO_ADDR *)OPENSSL_zalloc(sizeof(BIO_ADDR));
+    BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret));
+
     ret->sa.sa_family = AF_UNSPEC;
     return ret;
 }
@@ -227,7 +229,7 @@ static int addr_strings(const BIO_ADDR *ap, int numeric,
     if (1) {
 #ifdef AI_PASSIVE
         int ret = 0;
-        char host[NI_MAXHOST], serv[NI_MAXSERV];
+        char host[NI_MAXHOST] = "", serv[NI_MAXSERV] = "";
         int flags = 0;
 
         if (numeric)
@@ -249,6 +251,18 @@ static int addr_strings(const BIO_ADDR *ap, int numeric,
             }
             return 0;
         }
+
+        /* VMS getnameinfo() has a bug, it doesn't fill in serv, which
+         * leaves it with whatever garbage that happens to be there.
+         * However, we initialise serv with the empty string (serv[0]
+         * is therefore NUL), so it gets real easy to detect when things
+         * didn't go the way one might expect.
+         */
+        if (serv[0] == '\0') {
+            BIO_snprintf(serv, sizeof(serv), "%d",
+                         ntohs(BIO_ADDR_rawport(ap)));
+        }
+
         if (hostname)
             *hostname = OPENSSL_strdup(host);
         if (service)
@@ -340,7 +354,7 @@ socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap)
 
 /**********************************************************************
  *
- * Address into database
+ * Address info database
  *
  */
 
@@ -367,8 +381,24 @@ int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai)
 
 int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai)
 {
-    if (bai != NULL)
-        return bai->bai_protocol;
+    if (bai != NULL) {
+        if (bai->bai_protocol != 0)
+            return bai->bai_protocol;
+
+#ifdef AF_UNIX
+        if (bai->bai_family == AF_UNIX)
+            return 0;
+#endif
+
+        switch (bai->bai_socktype) {
+        case SOCK_STREAM:
+            return IPPROTO_TCP;
+        case SOCK_DGRAM:
+            return IPPROTO_UDP;
+        default:
+            break;
+        }
+    }
     return 0;
 }
 
@@ -505,7 +535,7 @@ int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
         }
     }
 
-    if (strchr(p, ':'))
+    if (p != NULL && strchr(p, ':'))
         goto spec_err;
 
     if (h != NULL && host != NULL) {
@@ -557,10 +587,10 @@ static int addrinfo_wrap(int family, int socktype,
 {
     OPENSSL_assert(bai != NULL);
 
-    *bai = (BIO_ADDRINFO *)OPENSSL_zalloc(sizeof(**bai));
-
+    *bai = OPENSSL_zalloc(sizeof(**bai));
     if (*bai == NULL)
         return 0;
+
     (*bai)->bai_family = family;
     (*bai)->bai_socktype = socktype;
     if (socktype == SOCK_STREAM)