make update
[openssl.git] / crypto / bio / b_addr.c
index 61714e5602aaf746d0874fb8706ec0d5aa8a51f6..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,9 @@
 
 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;
 }
 
@@ -84,6 +87,12 @@ void BIO_ADDR_free(BIO_ADDR *ap)
     OPENSSL_free(ap);
 }
 
+void BIO_ADDR_clear(BIO_ADDR *ap)
+{
+    memset(ap, 0, sizeof(*ap));
+    ap->sa.sa_family = AF_UNSPEC;
+}
+
 /*
  * BIO_ADDR_make - non-public routine to fill a BIO_ADDR with the contents
  * of a struct sockaddr.
@@ -214,10 +223,13 @@ unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap)
 static int addr_strings(const BIO_ADDR *ap, int numeric,
                         char **hostname, char **service)
 {
+    if (BIO_sock_init() != 1)
+        return 0;
+
     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)
@@ -239,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)
@@ -330,7 +354,7 @@ socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap)
 
 /**********************************************************************
  *
- * Address into database
+ * Address info database
  *
  */
 
@@ -357,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;
 }
 
@@ -495,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) {
@@ -547,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)
@@ -633,7 +673,11 @@ int BIO_lookup(const char *host, const char *service,
     }
 #endif
 
+    if (BIO_sock_init() != 1)
+        return 0;
+
     if (1) {
+        int gai_ret = 0;
 #ifdef AI_PASSIVE
         struct addrinfo hints;
 
@@ -655,7 +699,7 @@ int BIO_lookup(const char *host, const char *service,
         /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to
          * macro magic in bio_lcl.h
          */
-        switch (getaddrinfo(host, service, &hints, res)) {
+        switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
 # ifdef EAI_SYSTEM
         case EAI_SYSTEM:
             SYSerr(SYS_F_GETADDRINFO, get_last_socket_error());
@@ -667,7 +711,7 @@ int BIO_lookup(const char *host, const char *service,
             break;
         default:
             BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
-            ERR_add_error_data(1, gai_strerror(ret));
+            ERR_add_error_data(1, gai_strerror(gai_ret));
             break;
         }
     } else {