Refactoring BIO: new socket-handling functions, deprecate older ones
[openssl.git] / crypto / bio / b_sock.c
index a4fded5ec2a8517a7f6e572d5e5baeeb368c23f1..af40454e5c90ae23123d84f49abc595b44c1e069 100644 (file)
@@ -1,4 +1,3 @@
-/* crypto/bio/b_sock.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
-#define USE_SOCKETS
-#include "cryptlib.h"
-#include <openssl/bio.h>
-#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
-# include <netdb.h>
-# if defined(NETWARE_CLIB)
-#  include <sys/ioctl.h>
+#include "bio_lcl.h"
+#if defined(NETWARE_CLIB)
+# include <sys/ioctl.h>
 NETDB_DEFINE_CONTEXT
-# endif
 #endif
 #ifndef OPENSSL_NO_SOCK
 # include <openssl/dso.h>
@@ -94,6 +88,7 @@ static int wsa_init_done = 0;
 #  define WSAAPI
 # endif
 
+# if OPENSSL_API_COMPAT < 0x10100000L
 static int get_ip(const char *str, unsigned char *ip);
 int BIO_get_host_ip(const char *str, unsigned char *ip)
 {
@@ -200,6 +195,7 @@ int BIO_get_port(const char *str, unsigned short *port_ptr)
     }
     return (1);
 }
+# endif
 
 int BIO_sock_error(int sock)
 {
@@ -224,6 +220,7 @@ int BIO_sock_error(int sock)
         return (j);
 }
 
+# if OPENSSL_API_COMPAT < 0x10100000L
 struct hostent *BIO_gethostbyname(const char *name)
 {
     /*
@@ -236,6 +233,7 @@ struct hostent *BIO_gethostbyname(const char *name)
     return gethostbyname(name);
 # endif
 }
+# endif
 
 int BIO_sock_init(void)
 {
@@ -344,6 +342,7 @@ int BIO_socket_ioctl(int fd, long type, void *arg)
 }
 # endif                         /* __VMS_VER */
 
+# if OPENSSL_API_COMPAT < 0x10100000L
 /*
  * The reason I have implemented this instead of using sscanf is because
  * Visual C 1.52c gives an unresolved external when linking a DLL :-(
@@ -391,7 +390,7 @@ int BIO_get_accept_socket(char *host, int bind_mode)
         struct sockaddr_in6 sa_in6;
 # endif
     } server, client;
-    int s = INVALID_SOCKET, cs, addrlen;
+    int s = (int)INVALID_SOCKET, cs, addrlen;
     unsigned char ip[4];
     unsigned short port;
     char *str = NULL, *e;
@@ -400,10 +399,10 @@ int BIO_get_accept_socket(char *host, int bind_mode)
     int err_num;
 
     if (BIO_sock_init() != 1)
-        return (INVALID_SOCKET);
+        return ((int)INVALID_SOCKET);
 
-    if ((str = BUF_strdup(host)) == NULL)
-        return (INVALID_SOCKET);
+    if ((str = OPENSSL_strdup(host)) == NULL)
+        return ((int)INVALID_SOCKET);
 
     h = p = NULL;
     h = str;
@@ -484,7 +483,7 @@ int BIO_get_accept_socket(char *host, int bind_mode)
     if (!BIO_get_port(p, &port))
         goto err;
 
-    memset((char *)&server, 0, sizeof(server));
+    memset(&server, 0, sizeof(server));
     server.sa_in.sin_family = AF_INET;
     server.sa_in.sin_port = htons(port);
     addrlen = sizeof(server.sa_in);
@@ -503,7 +502,7 @@ int BIO_get_accept_socket(char *host, int bind_mode)
 
  again:
     s = socket(server.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
-    if (s == INVALID_SOCKET) {
+    if (s == (int)INVALID_SOCKET) {
         SYSerr(SYS_F_SOCKET, get_last_socket_error());
         ERR_add_error_data(3, "port='", host, "'");
         BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
@@ -545,11 +544,11 @@ int BIO_get_accept_socket(char *host, int bind_mode)
                     goto err;
             }
             cs = socket(client.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
-            if (cs != INVALID_SOCKET) {
+            if (cs != (int)INVALID_SOCKET) {
                 int ii;
                 ii = connect(cs, &client.sa, addrlen);
                 closesocket(cs);
-                if (ii == INVALID_SOCKET) {
+                if (ii == (int)INVALID_SOCKET) {
                     bind_mode = BIO_BIND_REUSEADDR;
                     closesocket(s);
                     goto again;
@@ -572,18 +571,17 @@ int BIO_get_accept_socket(char *host, int bind_mode)
     }
     ret = 1;
  err:
-    if (str != NULL)
-        OPENSSL_free(str);
-    if ((ret == 0) && (s != INVALID_SOCKET)) {
+    OPENSSL_free(str);
+    if ((ret == 0) && (s != (int)INVALID_SOCKET)) {
         closesocket(s);
-        s = INVALID_SOCKET;
+        s = (int)INVALID_SOCKET;
     }
     return (s);
 }
 
 int BIO_accept(int sock, char **addr)
 {
-    int ret = INVALID_SOCKET;
+    int ret = (int)INVALID_SOCKET;
     unsigned long l;
     unsigned short port;
     char *p;
@@ -632,7 +630,7 @@ int BIO_accept(int sock, char **addr)
         sa.len.i = (int)sa.len.s;
         /* use sa.len.i from this point */
     }
-    if (ret == INVALID_SOCKET) {
+    if (ret == (int)INVALID_SOCKET) {
         if (BIO_sock_should_retry(ret))
             return -2;
         SYSerr(SYS_F_ACCEPT, get_last_socket_error());
@@ -704,6 +702,7 @@ int BIO_accept(int sock, char **addr)
  end:
     return (ret);
 }
+# endif
 
 int BIO_set_tcp_ndelay(int s, int on)
 {
@@ -735,4 +734,34 @@ int BIO_socket_nbio(int s, int mode)
 # endif
     return (ret == 0);
 }
+
+int BIO_sock_info(int sock,
+                  enum BIO_sock_info_type type, union BIO_sock_info_u *info)
+{
+    switch (type) {
+    case BIO_SOCK_INFO_ADDRESS:
+        {
+            socklen_t addr_len;
+            int ret = 0;
+            addr_len = sizeof(*info->addr);
+            ret = getsockname(sock, BIO_ADDR_sockaddr_noconst(info->addr),
+                              &addr_len);
+            if (ret == -1) {
+                SYSerr(SYS_F_GETSOCKNAME, get_last_socket_error());
+                BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_ERROR);
+                return 0;
+            }
+            if (addr_len > sizeof(*info->addr)) {
+                BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS);
+                return 0;
+            }
+        }
+        break;
+    default:
+        BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_UNKNOWN_INFO_TYPE);
+        return 0;
+    }
+    return 1;
+}
+
 #endif