10Sstevel@tonic-gate /* crypto/bio/b_sock.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate * All rights reserved.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * This package is an SSL implementation written
60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions
110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation
130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate *
160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate * the code are not to be removed.
180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate * as the author of the parts of the library used.
200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate *
230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate * are met:
260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate * must display the following acknowledgement:
330Sstevel@tonic-gate * "This product includes cryptographic software written by
340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate * being used are not cryptographic related :-).
370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate *
410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate * SUCH DAMAGE.
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be
550Sstevel@tonic-gate * copied and put under another distribution licence
560Sstevel@tonic-gate * [including the GNU Public Licence.]
570Sstevel@tonic-gate */
580Sstevel@tonic-gate
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include <stdlib.h>
610Sstevel@tonic-gate #include <errno.h>
620Sstevel@tonic-gate #define USE_SOCKETS
630Sstevel@tonic-gate #include "cryptlib.h"
640Sstevel@tonic-gate #include <openssl/bio.h>
65*2139Sjp161948 #if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
66*2139Sjp161948 #include "netdb.h"
67*2139Sjp161948 #endif
68*2139Sjp161948
69*2139Sjp161948 #ifndef OPENSSL_NO_SOCK
700Sstevel@tonic-gate
710Sstevel@tonic-gate #ifdef OPENSSL_SYS_WIN16
720Sstevel@tonic-gate #define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
730Sstevel@tonic-gate #else
740Sstevel@tonic-gate #define SOCKET_PROTOCOL IPPROTO_TCP
750Sstevel@tonic-gate #endif
760Sstevel@tonic-gate
770Sstevel@tonic-gate #ifdef SO_MAXCONN
780Sstevel@tonic-gate #define MAX_LISTEN SO_MAXCONN
790Sstevel@tonic-gate #elif defined(SOMAXCONN)
800Sstevel@tonic-gate #define MAX_LISTEN SOMAXCONN
810Sstevel@tonic-gate #else
820Sstevel@tonic-gate #define MAX_LISTEN 32
830Sstevel@tonic-gate #endif
840Sstevel@tonic-gate
85*2139Sjp161948 #if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
860Sstevel@tonic-gate static int wsa_init_done=0;
870Sstevel@tonic-gate #endif
880Sstevel@tonic-gate
890Sstevel@tonic-gate #if 0
900Sstevel@tonic-gate static unsigned long BIO_ghbn_hits=0L;
910Sstevel@tonic-gate static unsigned long BIO_ghbn_miss=0L;
920Sstevel@tonic-gate
930Sstevel@tonic-gate #define GHBN_NUM 4
940Sstevel@tonic-gate static struct ghbn_cache_st
950Sstevel@tonic-gate {
960Sstevel@tonic-gate char name[129];
970Sstevel@tonic-gate struct hostent *ent;
980Sstevel@tonic-gate unsigned long order;
990Sstevel@tonic-gate } ghbn_cache[GHBN_NUM];
1000Sstevel@tonic-gate #endif
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate static int get_ip(const char *str,unsigned char *ip);
1030Sstevel@tonic-gate #if 0
1040Sstevel@tonic-gate static void ghbn_free(struct hostent *a);
1050Sstevel@tonic-gate static struct hostent *ghbn_dup(struct hostent *a);
1060Sstevel@tonic-gate #endif
BIO_get_host_ip(const char * str,unsigned char * ip)1070Sstevel@tonic-gate int BIO_get_host_ip(const char *str, unsigned char *ip)
1080Sstevel@tonic-gate {
1090Sstevel@tonic-gate int i;
1100Sstevel@tonic-gate int err = 1;
1110Sstevel@tonic-gate int locked = 0;
1120Sstevel@tonic-gate struct hostent *he;
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate i=get_ip(str,ip);
1150Sstevel@tonic-gate if (i < 0)
1160Sstevel@tonic-gate {
1170Sstevel@tonic-gate BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS);
1180Sstevel@tonic-gate goto err;
1190Sstevel@tonic-gate }
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate /* At this point, we have something that is most probably correct
1220Sstevel@tonic-gate in some way, so let's init the socket. */
1230Sstevel@tonic-gate if (BIO_sock_init() != 1)
1240Sstevel@tonic-gate return 0; /* don't generate another error code here */
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate /* If the string actually contained an IP address, we need not do
1270Sstevel@tonic-gate anything more */
1280Sstevel@tonic-gate if (i > 0) return(1);
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate /* do a gethostbyname */
1310Sstevel@tonic-gate CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
1320Sstevel@tonic-gate locked = 1;
1330Sstevel@tonic-gate he=BIO_gethostbyname(str);
1340Sstevel@tonic-gate if (he == NULL)
1350Sstevel@tonic-gate {
1360Sstevel@tonic-gate BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP);
1370Sstevel@tonic-gate goto err;
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate /* cast to short because of win16 winsock definition */
1410Sstevel@tonic-gate if ((short)he->h_addrtype != AF_INET)
1420Sstevel@tonic-gate {
1430Sstevel@tonic-gate BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
1440Sstevel@tonic-gate goto err;
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate for (i=0; i<4; i++)
1470Sstevel@tonic-gate ip[i]=he->h_addr_list[0][i];
1480Sstevel@tonic-gate err = 0;
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate err:
1510Sstevel@tonic-gate if (locked)
1520Sstevel@tonic-gate CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
1530Sstevel@tonic-gate if (err)
1540Sstevel@tonic-gate {
1550Sstevel@tonic-gate ERR_add_error_data(2,"host=",str);
1560Sstevel@tonic-gate return 0;
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate else
1590Sstevel@tonic-gate return 1;
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate
BIO_get_port(const char * str,unsigned short * port_ptr)1620Sstevel@tonic-gate int BIO_get_port(const char *str, unsigned short *port_ptr)
1630Sstevel@tonic-gate {
1640Sstevel@tonic-gate int i;
1650Sstevel@tonic-gate struct servent *s;
1660Sstevel@tonic-gate
1670Sstevel@tonic-gate if (str == NULL)
1680Sstevel@tonic-gate {
1690Sstevel@tonic-gate BIOerr(BIO_F_BIO_GET_PORT,BIO_R_NO_PORT_DEFINED);
1700Sstevel@tonic-gate return(0);
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate i=atoi(str);
1730Sstevel@tonic-gate if (i != 0)
1740Sstevel@tonic-gate *port_ptr=(unsigned short)i;
1750Sstevel@tonic-gate else
1760Sstevel@tonic-gate {
1770Sstevel@tonic-gate CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
1780Sstevel@tonic-gate /* Note: under VMS with SOCKETSHR, it seems like the first
1790Sstevel@tonic-gate * parameter is 'char *', instead of 'const char *'
1800Sstevel@tonic-gate */
1810Sstevel@tonic-gate s=getservbyname(
1820Sstevel@tonic-gate #ifndef CONST_STRICT
1830Sstevel@tonic-gate (char *)
1840Sstevel@tonic-gate #endif
1850Sstevel@tonic-gate str,"tcp");
1860Sstevel@tonic-gate if(s != NULL)
1870Sstevel@tonic-gate *port_ptr=ntohs((unsigned short)s->s_port);
1880Sstevel@tonic-gate CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
1890Sstevel@tonic-gate if(s == NULL)
1900Sstevel@tonic-gate {
1910Sstevel@tonic-gate if (strcmp(str,"http") == 0)
1920Sstevel@tonic-gate *port_ptr=80;
1930Sstevel@tonic-gate else if (strcmp(str,"telnet") == 0)
1940Sstevel@tonic-gate *port_ptr=23;
1950Sstevel@tonic-gate else if (strcmp(str,"socks") == 0)
1960Sstevel@tonic-gate *port_ptr=1080;
1970Sstevel@tonic-gate else if (strcmp(str,"https") == 0)
1980Sstevel@tonic-gate *port_ptr=443;
1990Sstevel@tonic-gate else if (strcmp(str,"ssl") == 0)
2000Sstevel@tonic-gate *port_ptr=443;
2010Sstevel@tonic-gate else if (strcmp(str,"ftp") == 0)
2020Sstevel@tonic-gate *port_ptr=21;
2030Sstevel@tonic-gate else if (strcmp(str,"gopher") == 0)
2040Sstevel@tonic-gate *port_ptr=70;
2050Sstevel@tonic-gate #if 0
2060Sstevel@tonic-gate else if (strcmp(str,"wais") == 0)
2070Sstevel@tonic-gate *port_ptr=21;
2080Sstevel@tonic-gate #endif
2090Sstevel@tonic-gate else
2100Sstevel@tonic-gate {
2110Sstevel@tonic-gate SYSerr(SYS_F_GETSERVBYNAME,get_last_socket_error());
2120Sstevel@tonic-gate ERR_add_error_data(3,"service='",str,"'");
2130Sstevel@tonic-gate return(0);
2140Sstevel@tonic-gate }
2150Sstevel@tonic-gate }
2160Sstevel@tonic-gate }
2170Sstevel@tonic-gate return(1);
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate
BIO_sock_error(int sock)2200Sstevel@tonic-gate int BIO_sock_error(int sock)
2210Sstevel@tonic-gate {
2220Sstevel@tonic-gate int j,i;
2230Sstevel@tonic-gate int size;
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate size=sizeof(int);
2260Sstevel@tonic-gate /* Note: under Windows the third parameter is of type (char *)
2270Sstevel@tonic-gate * whereas under other systems it is (void *) if you don't have
2280Sstevel@tonic-gate * a cast it will choke the compiler: if you do have a cast then
2290Sstevel@tonic-gate * you can either go for (char *) or (void *).
2300Sstevel@tonic-gate */
2310Sstevel@tonic-gate i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void *)&j,(void *)&size);
2320Sstevel@tonic-gate if (i < 0)
2330Sstevel@tonic-gate return(1);
2340Sstevel@tonic-gate else
2350Sstevel@tonic-gate return(j);
2360Sstevel@tonic-gate }
2370Sstevel@tonic-gate
2380Sstevel@tonic-gate #if 0
2390Sstevel@tonic-gate long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
2400Sstevel@tonic-gate {
2410Sstevel@tonic-gate int i;
2420Sstevel@tonic-gate char **p;
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate switch (cmd)
2450Sstevel@tonic-gate {
2460Sstevel@tonic-gate case BIO_GHBN_CTRL_HITS:
2470Sstevel@tonic-gate return(BIO_ghbn_hits);
2480Sstevel@tonic-gate /* break; */
2490Sstevel@tonic-gate case BIO_GHBN_CTRL_MISSES:
2500Sstevel@tonic-gate return(BIO_ghbn_miss);
2510Sstevel@tonic-gate /* break; */
2520Sstevel@tonic-gate case BIO_GHBN_CTRL_CACHE_SIZE:
2530Sstevel@tonic-gate return(GHBN_NUM);
2540Sstevel@tonic-gate /* break; */
2550Sstevel@tonic-gate case BIO_GHBN_CTRL_GET_ENTRY:
2560Sstevel@tonic-gate if ((iarg >= 0) && (iarg <GHBN_NUM) &&
2570Sstevel@tonic-gate (ghbn_cache[iarg].order > 0))
2580Sstevel@tonic-gate {
2590Sstevel@tonic-gate p=(char **)parg;
2600Sstevel@tonic-gate if (p == NULL) return(0);
2610Sstevel@tonic-gate *p=ghbn_cache[iarg].name;
2620Sstevel@tonic-gate ghbn_cache[iarg].name[128]='\0';
2630Sstevel@tonic-gate return(1);
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate return(0);
2660Sstevel@tonic-gate /* break; */
2670Sstevel@tonic-gate case BIO_GHBN_CTRL_FLUSH:
2680Sstevel@tonic-gate for (i=0; i<GHBN_NUM; i++)
2690Sstevel@tonic-gate ghbn_cache[i].order=0;
2700Sstevel@tonic-gate break;
2710Sstevel@tonic-gate default:
2720Sstevel@tonic-gate return(0);
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate return(1);
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate #endif
2770Sstevel@tonic-gate
2780Sstevel@tonic-gate #if 0
2790Sstevel@tonic-gate static struct hostent *ghbn_dup(struct hostent *a)
2800Sstevel@tonic-gate {
2810Sstevel@tonic-gate struct hostent *ret;
2820Sstevel@tonic-gate int i,j;
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate MemCheck_off();
2850Sstevel@tonic-gate ret=(struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
2860Sstevel@tonic-gate if (ret == NULL) return(NULL);
2870Sstevel@tonic-gate memset(ret,0,sizeof(struct hostent));
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate for (i=0; a->h_aliases[i] != NULL; i++)
2900Sstevel@tonic-gate ;
2910Sstevel@tonic-gate i++;
2920Sstevel@tonic-gate ret->h_aliases = (char **)OPENSSL_malloc(i*sizeof(char *));
2930Sstevel@tonic-gate if (ret->h_aliases == NULL)
2940Sstevel@tonic-gate goto err;
2950Sstevel@tonic-gate memset(ret->h_aliases, 0, i*sizeof(char *));
2960Sstevel@tonic-gate
2970Sstevel@tonic-gate for (i=0; a->h_addr_list[i] != NULL; i++)
2980Sstevel@tonic-gate ;
2990Sstevel@tonic-gate i++;
3000Sstevel@tonic-gate ret->h_addr_list=(char **)OPENSSL_malloc(i*sizeof(char *));
3010Sstevel@tonic-gate if (ret->h_addr_list == NULL)
3020Sstevel@tonic-gate goto err;
3030Sstevel@tonic-gate memset(ret->h_addr_list, 0, i*sizeof(char *));
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate j=strlen(a->h_name)+1;
3060Sstevel@tonic-gate if ((ret->h_name=OPENSSL_malloc(j)) == NULL) goto err;
3070Sstevel@tonic-gate memcpy((char *)ret->h_name,a->h_name,j);
3080Sstevel@tonic-gate for (i=0; a->h_aliases[i] != NULL; i++)
3090Sstevel@tonic-gate {
3100Sstevel@tonic-gate j=strlen(a->h_aliases[i])+1;
3110Sstevel@tonic-gate if ((ret->h_aliases[i]=OPENSSL_malloc(j)) == NULL) goto err;
3120Sstevel@tonic-gate memcpy(ret->h_aliases[i],a->h_aliases[i],j);
3130Sstevel@tonic-gate }
3140Sstevel@tonic-gate ret->h_length=a->h_length;
3150Sstevel@tonic-gate ret->h_addrtype=a->h_addrtype;
3160Sstevel@tonic-gate for (i=0; a->h_addr_list[i] != NULL; i++)
3170Sstevel@tonic-gate {
3180Sstevel@tonic-gate if ((ret->h_addr_list[i]=OPENSSL_malloc(a->h_length)) == NULL)
3190Sstevel@tonic-gate goto err;
3200Sstevel@tonic-gate memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length);
3210Sstevel@tonic-gate }
3220Sstevel@tonic-gate if (0)
3230Sstevel@tonic-gate {
3240Sstevel@tonic-gate err:
3250Sstevel@tonic-gate if (ret != NULL)
3260Sstevel@tonic-gate ghbn_free(ret);
3270Sstevel@tonic-gate ret=NULL;
3280Sstevel@tonic-gate }
3290Sstevel@tonic-gate MemCheck_on();
3300Sstevel@tonic-gate return(ret);
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate
3330Sstevel@tonic-gate static void ghbn_free(struct hostent *a)
3340Sstevel@tonic-gate {
3350Sstevel@tonic-gate int i;
3360Sstevel@tonic-gate
3370Sstevel@tonic-gate if(a == NULL)
3380Sstevel@tonic-gate return;
3390Sstevel@tonic-gate
3400Sstevel@tonic-gate if (a->h_aliases != NULL)
3410Sstevel@tonic-gate {
3420Sstevel@tonic-gate for (i=0; a->h_aliases[i] != NULL; i++)
3430Sstevel@tonic-gate OPENSSL_free(a->h_aliases[i]);
3440Sstevel@tonic-gate OPENSSL_free(a->h_aliases);
3450Sstevel@tonic-gate }
3460Sstevel@tonic-gate if (a->h_addr_list != NULL)
3470Sstevel@tonic-gate {
3480Sstevel@tonic-gate for (i=0; a->h_addr_list[i] != NULL; i++)
3490Sstevel@tonic-gate OPENSSL_free(a->h_addr_list[i]);
3500Sstevel@tonic-gate OPENSSL_free(a->h_addr_list);
3510Sstevel@tonic-gate }
3520Sstevel@tonic-gate if (a->h_name != NULL) OPENSSL_free(a->h_name);
3530Sstevel@tonic-gate OPENSSL_free(a);
3540Sstevel@tonic-gate }
3550Sstevel@tonic-gate
3560Sstevel@tonic-gate #endif
3570Sstevel@tonic-gate
BIO_gethostbyname(const char * name)3580Sstevel@tonic-gate struct hostent *BIO_gethostbyname(const char *name)
3590Sstevel@tonic-gate {
3600Sstevel@tonic-gate #if 1
3610Sstevel@tonic-gate /* Caching gethostbyname() results forever is wrong,
3620Sstevel@tonic-gate * so we have to let the true gethostbyname() worry about this */
3630Sstevel@tonic-gate return gethostbyname(name);
3640Sstevel@tonic-gate #else
3650Sstevel@tonic-gate struct hostent *ret;
3660Sstevel@tonic-gate int i,lowi=0,j;
3670Sstevel@tonic-gate unsigned long low= (unsigned long)-1;
3680Sstevel@tonic-gate
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate # if 0
3710Sstevel@tonic-gate /* It doesn't make sense to use locking here: The function interface
3720Sstevel@tonic-gate * is not thread-safe, because threads can never be sure when
3730Sstevel@tonic-gate * some other thread destroys the data they were given a pointer to.
3740Sstevel@tonic-gate */
3750Sstevel@tonic-gate CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
3760Sstevel@tonic-gate # endif
3770Sstevel@tonic-gate j=strlen(name);
3780Sstevel@tonic-gate if (j < 128)
3790Sstevel@tonic-gate {
3800Sstevel@tonic-gate for (i=0; i<GHBN_NUM; i++)
3810Sstevel@tonic-gate {
3820Sstevel@tonic-gate if (low > ghbn_cache[i].order)
3830Sstevel@tonic-gate {
3840Sstevel@tonic-gate low=ghbn_cache[i].order;
3850Sstevel@tonic-gate lowi=i;
3860Sstevel@tonic-gate }
3870Sstevel@tonic-gate if (ghbn_cache[i].order > 0)
3880Sstevel@tonic-gate {
3890Sstevel@tonic-gate if (strncmp(name,ghbn_cache[i].name,128) == 0)
3900Sstevel@tonic-gate break;
3910Sstevel@tonic-gate }
3920Sstevel@tonic-gate }
3930Sstevel@tonic-gate }
3940Sstevel@tonic-gate else
3950Sstevel@tonic-gate i=GHBN_NUM;
3960Sstevel@tonic-gate
3970Sstevel@tonic-gate if (i == GHBN_NUM) /* no hit*/
3980Sstevel@tonic-gate {
3990Sstevel@tonic-gate BIO_ghbn_miss++;
4000Sstevel@tonic-gate /* Note: under VMS with SOCKETSHR, it seems like the first
4010Sstevel@tonic-gate * parameter is 'char *', instead of 'const char *'
4020Sstevel@tonic-gate */
4030Sstevel@tonic-gate ret=gethostbyname(
4040Sstevel@tonic-gate # ifndef CONST_STRICT
4050Sstevel@tonic-gate (char *)
4060Sstevel@tonic-gate # endif
4070Sstevel@tonic-gate name);
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate if (ret == NULL)
4100Sstevel@tonic-gate goto end;
4110Sstevel@tonic-gate if (j > 128) /* too big to cache */
4120Sstevel@tonic-gate {
4130Sstevel@tonic-gate # if 0
4140Sstevel@tonic-gate /* If we were trying to make this function thread-safe (which
4150Sstevel@tonic-gate * is bound to fail), we'd have to give up in this case
4160Sstevel@tonic-gate * (or allocate more memory). */
4170Sstevel@tonic-gate ret = NULL;
4180Sstevel@tonic-gate # endif
4190Sstevel@tonic-gate goto end;
4200Sstevel@tonic-gate }
4210Sstevel@tonic-gate
4220Sstevel@tonic-gate /* else add to cache */
4230Sstevel@tonic-gate if (ghbn_cache[lowi].ent != NULL)
4240Sstevel@tonic-gate ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
4250Sstevel@tonic-gate ghbn_cache[lowi].name[0] = '\0';
4260Sstevel@tonic-gate
4270Sstevel@tonic-gate if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL)
4280Sstevel@tonic-gate {
4290Sstevel@tonic-gate BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE);
4300Sstevel@tonic-gate goto end;
4310Sstevel@tonic-gate }
4320Sstevel@tonic-gate strncpy(ghbn_cache[lowi].name,name,128);
4330Sstevel@tonic-gate ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits;
4340Sstevel@tonic-gate }
4350Sstevel@tonic-gate else
4360Sstevel@tonic-gate {
4370Sstevel@tonic-gate BIO_ghbn_hits++;
4380Sstevel@tonic-gate ret= ghbn_cache[i].ent;
4390Sstevel@tonic-gate ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits;
4400Sstevel@tonic-gate }
4410Sstevel@tonic-gate end:
4420Sstevel@tonic-gate # if 0
4430Sstevel@tonic-gate CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
4440Sstevel@tonic-gate # endif
4450Sstevel@tonic-gate return(ret);
4460Sstevel@tonic-gate #endif
4470Sstevel@tonic-gate }
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate
BIO_sock_init(void)4500Sstevel@tonic-gate int BIO_sock_init(void)
4510Sstevel@tonic-gate {
4520Sstevel@tonic-gate #ifdef OPENSSL_SYS_WINDOWS
4530Sstevel@tonic-gate static struct WSAData wsa_state;
4540Sstevel@tonic-gate
4550Sstevel@tonic-gate if (!wsa_init_done)
4560Sstevel@tonic-gate {
4570Sstevel@tonic-gate int err;
4580Sstevel@tonic-gate
4590Sstevel@tonic-gate #ifdef SIGINT
4600Sstevel@tonic-gate signal(SIGINT,(void (*)(int))BIO_sock_cleanup);
4610Sstevel@tonic-gate #endif
4620Sstevel@tonic-gate wsa_init_done=1;
4630Sstevel@tonic-gate memset(&wsa_state,0,sizeof(wsa_state));
4640Sstevel@tonic-gate if (WSAStartup(0x0101,&wsa_state)!=0)
4650Sstevel@tonic-gate {
4660Sstevel@tonic-gate err=WSAGetLastError();
4670Sstevel@tonic-gate SYSerr(SYS_F_WSASTARTUP,err);
4680Sstevel@tonic-gate BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
4690Sstevel@tonic-gate return(-1);
4700Sstevel@tonic-gate }
4710Sstevel@tonic-gate }
4720Sstevel@tonic-gate #endif /* OPENSSL_SYS_WINDOWS */
4730Sstevel@tonic-gate #ifdef WATT32
4740Sstevel@tonic-gate extern int _watt_do_exit;
4750Sstevel@tonic-gate _watt_do_exit = 0; /* don't make sock_init() call exit() */
4760Sstevel@tonic-gate if (sock_init())
4770Sstevel@tonic-gate return (-1);
4780Sstevel@tonic-gate #endif
479*2139Sjp161948
480*2139Sjp161948 #if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
481*2139Sjp161948 WORD wVerReq;
482*2139Sjp161948 WSADATA wsaData;
483*2139Sjp161948 int err;
484*2139Sjp161948
485*2139Sjp161948 if (!wsa_init_done)
486*2139Sjp161948 {
487*2139Sjp161948
488*2139Sjp161948 # ifdef SIGINT
489*2139Sjp161948 signal(SIGINT,(void (*)(int))BIO_sock_cleanup);
490*2139Sjp161948 # endif
491*2139Sjp161948
492*2139Sjp161948 wsa_init_done=1;
493*2139Sjp161948 wVerReq = MAKEWORD( 2, 0 );
494*2139Sjp161948 err = WSAStartup(wVerReq,&wsaData);
495*2139Sjp161948 if (err != 0)
496*2139Sjp161948 {
497*2139Sjp161948 SYSerr(SYS_F_WSASTARTUP,err);
498*2139Sjp161948 BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
499*2139Sjp161948 return(-1);
500*2139Sjp161948 }
501*2139Sjp161948 }
502*2139Sjp161948 #endif
503*2139Sjp161948
5040Sstevel@tonic-gate return(1);
5050Sstevel@tonic-gate }
5060Sstevel@tonic-gate
BIO_sock_cleanup(void)5070Sstevel@tonic-gate void BIO_sock_cleanup(void)
5080Sstevel@tonic-gate {
5090Sstevel@tonic-gate #ifdef OPENSSL_SYS_WINDOWS
5100Sstevel@tonic-gate if (wsa_init_done)
5110Sstevel@tonic-gate {
5120Sstevel@tonic-gate wsa_init_done=0;
5130Sstevel@tonic-gate #ifndef OPENSSL_SYS_WINCE
5140Sstevel@tonic-gate WSACancelBlockingCall();
5150Sstevel@tonic-gate #endif
5160Sstevel@tonic-gate WSACleanup();
5170Sstevel@tonic-gate }
518*2139Sjp161948 #elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
519*2139Sjp161948 if (wsa_init_done)
520*2139Sjp161948 {
521*2139Sjp161948 wsa_init_done=0;
522*2139Sjp161948 WSACleanup();
523*2139Sjp161948 }
5240Sstevel@tonic-gate #endif
5250Sstevel@tonic-gate }
5260Sstevel@tonic-gate
5270Sstevel@tonic-gate #if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
5280Sstevel@tonic-gate
BIO_socket_ioctl(int fd,long type,void * arg)5290Sstevel@tonic-gate int BIO_socket_ioctl(int fd, long type, void *arg)
5300Sstevel@tonic-gate {
5310Sstevel@tonic-gate int i;
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate #ifdef __DJGPP__
5340Sstevel@tonic-gate i=ioctlsocket(fd,type,(char *)arg);
5350Sstevel@tonic-gate #else
5360Sstevel@tonic-gate i=ioctlsocket(fd,type,arg);
5370Sstevel@tonic-gate #endif /* __DJGPP__ */
5380Sstevel@tonic-gate if (i < 0)
5390Sstevel@tonic-gate SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error());
5400Sstevel@tonic-gate return(i);
5410Sstevel@tonic-gate }
5420Sstevel@tonic-gate #endif /* __VMS_VER */
5430Sstevel@tonic-gate
5440Sstevel@tonic-gate /* The reason I have implemented this instead of using sscanf is because
5450Sstevel@tonic-gate * Visual C 1.52c gives an unresolved external when linking a DLL :-( */
get_ip(const char * str,unsigned char ip[4])5460Sstevel@tonic-gate static int get_ip(const char *str, unsigned char ip[4])
5470Sstevel@tonic-gate {
5480Sstevel@tonic-gate unsigned int tmp[4];
5490Sstevel@tonic-gate int num=0,c,ok=0;
5500Sstevel@tonic-gate
5510Sstevel@tonic-gate tmp[0]=tmp[1]=tmp[2]=tmp[3]=0;
5520Sstevel@tonic-gate
5530Sstevel@tonic-gate for (;;)
5540Sstevel@tonic-gate {
5550Sstevel@tonic-gate c= *(str++);
5560Sstevel@tonic-gate if ((c >= '0') && (c <= '9'))
5570Sstevel@tonic-gate {
5580Sstevel@tonic-gate ok=1;
5590Sstevel@tonic-gate tmp[num]=tmp[num]*10+c-'0';
5600Sstevel@tonic-gate if (tmp[num] > 255) return(0);
5610Sstevel@tonic-gate }
5620Sstevel@tonic-gate else if (c == '.')
5630Sstevel@tonic-gate {
5640Sstevel@tonic-gate if (!ok) return(-1);
5650Sstevel@tonic-gate if (num == 3) return(0);
5660Sstevel@tonic-gate num++;
5670Sstevel@tonic-gate ok=0;
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate else if (c == '\0' && (num == 3) && ok)
5700Sstevel@tonic-gate break;
5710Sstevel@tonic-gate else
5720Sstevel@tonic-gate return(0);
5730Sstevel@tonic-gate }
5740Sstevel@tonic-gate ip[0]=tmp[0];
5750Sstevel@tonic-gate ip[1]=tmp[1];
5760Sstevel@tonic-gate ip[2]=tmp[2];
5770Sstevel@tonic-gate ip[3]=tmp[3];
5780Sstevel@tonic-gate return(1);
5790Sstevel@tonic-gate }
5800Sstevel@tonic-gate
BIO_get_accept_socket(char * host,int bind_mode)5810Sstevel@tonic-gate int BIO_get_accept_socket(char *host, int bind_mode)
5820Sstevel@tonic-gate {
5830Sstevel@tonic-gate int ret=0;
5840Sstevel@tonic-gate struct sockaddr_in server,client;
5850Sstevel@tonic-gate int s=INVALID_SOCKET,cs;
5860Sstevel@tonic-gate unsigned char ip[4];
5870Sstevel@tonic-gate unsigned short port;
5880Sstevel@tonic-gate char *str=NULL,*e;
5890Sstevel@tonic-gate const char *h,*p;
5900Sstevel@tonic-gate unsigned long l;
5910Sstevel@tonic-gate int err_num;
5920Sstevel@tonic-gate
5930Sstevel@tonic-gate if (BIO_sock_init() != 1) return(INVALID_SOCKET);
5940Sstevel@tonic-gate
5950Sstevel@tonic-gate if ((str=BUF_strdup(host)) == NULL) return(INVALID_SOCKET);
5960Sstevel@tonic-gate
5970Sstevel@tonic-gate h=p=NULL;
5980Sstevel@tonic-gate h=str;
5990Sstevel@tonic-gate for (e=str; *e; e++)
6000Sstevel@tonic-gate {
6010Sstevel@tonic-gate if (*e == ':')
6020Sstevel@tonic-gate {
6030Sstevel@tonic-gate p= &(e[1]);
6040Sstevel@tonic-gate *e='\0';
6050Sstevel@tonic-gate }
6060Sstevel@tonic-gate else if (*e == '/')
6070Sstevel@tonic-gate {
6080Sstevel@tonic-gate *e='\0';
6090Sstevel@tonic-gate break;
6100Sstevel@tonic-gate }
6110Sstevel@tonic-gate }
6120Sstevel@tonic-gate
6130Sstevel@tonic-gate if (p == NULL)
6140Sstevel@tonic-gate {
6150Sstevel@tonic-gate p=h;
6160Sstevel@tonic-gate h="*";
6170Sstevel@tonic-gate }
6180Sstevel@tonic-gate
6190Sstevel@tonic-gate if (!BIO_get_port(p,&port)) goto err;
6200Sstevel@tonic-gate
6210Sstevel@tonic-gate memset((char *)&server,0,sizeof(server));
6220Sstevel@tonic-gate server.sin_family=AF_INET;
6230Sstevel@tonic-gate server.sin_port=htons(port);
6240Sstevel@tonic-gate
6250Sstevel@tonic-gate if (strcmp(h,"*") == 0)
6260Sstevel@tonic-gate server.sin_addr.s_addr=INADDR_ANY;
6270Sstevel@tonic-gate else
6280Sstevel@tonic-gate {
6290Sstevel@tonic-gate if (!BIO_get_host_ip(h,&(ip[0]))) goto err;
6300Sstevel@tonic-gate l=(unsigned long)
6310Sstevel@tonic-gate ((unsigned long)ip[0]<<24L)|
6320Sstevel@tonic-gate ((unsigned long)ip[1]<<16L)|
6330Sstevel@tonic-gate ((unsigned long)ip[2]<< 8L)|
6340Sstevel@tonic-gate ((unsigned long)ip[3]);
6350Sstevel@tonic-gate server.sin_addr.s_addr=htonl(l);
6360Sstevel@tonic-gate }
6370Sstevel@tonic-gate
6380Sstevel@tonic-gate again:
6390Sstevel@tonic-gate s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
6400Sstevel@tonic-gate if (s == INVALID_SOCKET)
6410Sstevel@tonic-gate {
6420Sstevel@tonic-gate SYSerr(SYS_F_SOCKET,get_last_socket_error());
6430Sstevel@tonic-gate ERR_add_error_data(3,"port='",host,"'");
6440Sstevel@tonic-gate BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET);
6450Sstevel@tonic-gate goto err;
6460Sstevel@tonic-gate }
6470Sstevel@tonic-gate
6480Sstevel@tonic-gate #ifdef SO_REUSEADDR
6490Sstevel@tonic-gate if (bind_mode == BIO_BIND_REUSEADDR)
6500Sstevel@tonic-gate {
6510Sstevel@tonic-gate int i=1;
6520Sstevel@tonic-gate
6530Sstevel@tonic-gate ret=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i));
6540Sstevel@tonic-gate bind_mode=BIO_BIND_NORMAL;
6550Sstevel@tonic-gate }
6560Sstevel@tonic-gate #endif
6570Sstevel@tonic-gate if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
6580Sstevel@tonic-gate {
6590Sstevel@tonic-gate #ifdef SO_REUSEADDR
6600Sstevel@tonic-gate err_num=get_last_socket_error();
6610Sstevel@tonic-gate if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
6620Sstevel@tonic-gate (err_num == EADDRINUSE))
6630Sstevel@tonic-gate {
6640Sstevel@tonic-gate memcpy((char *)&client,(char *)&server,sizeof(server));
6650Sstevel@tonic-gate if (strcmp(h,"*") == 0)
6660Sstevel@tonic-gate client.sin_addr.s_addr=htonl(0x7F000001);
6670Sstevel@tonic-gate cs=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
6680Sstevel@tonic-gate if (cs != INVALID_SOCKET)
6690Sstevel@tonic-gate {
6700Sstevel@tonic-gate int ii;
6710Sstevel@tonic-gate ii=connect(cs,(struct sockaddr *)&client,
6720Sstevel@tonic-gate sizeof(client));
6730Sstevel@tonic-gate closesocket(cs);
6740Sstevel@tonic-gate if (ii == INVALID_SOCKET)
6750Sstevel@tonic-gate {
6760Sstevel@tonic-gate bind_mode=BIO_BIND_REUSEADDR;
6770Sstevel@tonic-gate closesocket(s);
6780Sstevel@tonic-gate goto again;
6790Sstevel@tonic-gate }
6800Sstevel@tonic-gate /* else error */
6810Sstevel@tonic-gate }
6820Sstevel@tonic-gate /* else error */
6830Sstevel@tonic-gate }
6840Sstevel@tonic-gate #endif
6850Sstevel@tonic-gate SYSerr(SYS_F_BIND,err_num);
6860Sstevel@tonic-gate ERR_add_error_data(3,"port='",host,"'");
6870Sstevel@tonic-gate BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET);
6880Sstevel@tonic-gate goto err;
6890Sstevel@tonic-gate }
6900Sstevel@tonic-gate if (listen(s,MAX_LISTEN) == -1)
6910Sstevel@tonic-gate {
6920Sstevel@tonic-gate SYSerr(SYS_F_BIND,get_last_socket_error());
6930Sstevel@tonic-gate ERR_add_error_data(3,"port='",host,"'");
6940Sstevel@tonic-gate BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_LISTEN_SOCKET);
6950Sstevel@tonic-gate goto err;
6960Sstevel@tonic-gate }
6970Sstevel@tonic-gate ret=1;
6980Sstevel@tonic-gate err:
6990Sstevel@tonic-gate if (str != NULL) OPENSSL_free(str);
7000Sstevel@tonic-gate if ((ret == 0) && (s != INVALID_SOCKET))
7010Sstevel@tonic-gate {
7020Sstevel@tonic-gate closesocket(s);
7030Sstevel@tonic-gate s= INVALID_SOCKET;
7040Sstevel@tonic-gate }
7050Sstevel@tonic-gate return(s);
7060Sstevel@tonic-gate }
7070Sstevel@tonic-gate
BIO_accept(int sock,char ** addr)7080Sstevel@tonic-gate int BIO_accept(int sock, char **addr)
7090Sstevel@tonic-gate {
7100Sstevel@tonic-gate int ret=INVALID_SOCKET;
7110Sstevel@tonic-gate static struct sockaddr_in from;
7120Sstevel@tonic-gate unsigned long l;
7130Sstevel@tonic-gate unsigned short port;
7140Sstevel@tonic-gate int len;
7150Sstevel@tonic-gate char *p;
7160Sstevel@tonic-gate
7170Sstevel@tonic-gate memset((char *)&from,0,sizeof(from));
7180Sstevel@tonic-gate len=sizeof(from);
7190Sstevel@tonic-gate /* Note: under VMS with SOCKETSHR the fourth parameter is currently
7200Sstevel@tonic-gate * of type (int *) whereas under other systems it is (void *) if
7210Sstevel@tonic-gate * you don't have a cast it will choke the compiler: if you do
7220Sstevel@tonic-gate * have a cast then you can either go for (int *) or (void *).
7230Sstevel@tonic-gate */
7240Sstevel@tonic-gate ret=accept(sock,(struct sockaddr *)&from,(void *)&len);
7250Sstevel@tonic-gate if (ret == INVALID_SOCKET)
7260Sstevel@tonic-gate {
7270Sstevel@tonic-gate if(BIO_sock_should_retry(ret)) return -2;
7280Sstevel@tonic-gate SYSerr(SYS_F_ACCEPT,get_last_socket_error());
7290Sstevel@tonic-gate BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR);
7300Sstevel@tonic-gate goto end;
7310Sstevel@tonic-gate }
7320Sstevel@tonic-gate
7330Sstevel@tonic-gate if (addr == NULL) goto end;
7340Sstevel@tonic-gate
7350Sstevel@tonic-gate l=ntohl(from.sin_addr.s_addr);
7360Sstevel@tonic-gate port=ntohs(from.sin_port);
7370Sstevel@tonic-gate if (*addr == NULL)
7380Sstevel@tonic-gate {
7390Sstevel@tonic-gate if ((p=OPENSSL_malloc(24)) == NULL)
7400Sstevel@tonic-gate {
7410Sstevel@tonic-gate BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
7420Sstevel@tonic-gate goto end;
7430Sstevel@tonic-gate }
7440Sstevel@tonic-gate *addr=p;
7450Sstevel@tonic-gate }
7460Sstevel@tonic-gate BIO_snprintf(*addr,24,"%d.%d.%d.%d:%d",
7470Sstevel@tonic-gate (unsigned char)(l>>24L)&0xff,
7480Sstevel@tonic-gate (unsigned char)(l>>16L)&0xff,
7490Sstevel@tonic-gate (unsigned char)(l>> 8L)&0xff,
7500Sstevel@tonic-gate (unsigned char)(l )&0xff,
7510Sstevel@tonic-gate port);
7520Sstevel@tonic-gate end:
7530Sstevel@tonic-gate return(ret);
7540Sstevel@tonic-gate }
7550Sstevel@tonic-gate
BIO_set_tcp_ndelay(int s,int on)7560Sstevel@tonic-gate int BIO_set_tcp_ndelay(int s, int on)
7570Sstevel@tonic-gate {
7580Sstevel@tonic-gate int ret=0;
7590Sstevel@tonic-gate #if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
7600Sstevel@tonic-gate int opt;
7610Sstevel@tonic-gate
7620Sstevel@tonic-gate #ifdef SOL_TCP
7630Sstevel@tonic-gate opt=SOL_TCP;
7640Sstevel@tonic-gate #else
7650Sstevel@tonic-gate #ifdef IPPROTO_TCP
7660Sstevel@tonic-gate opt=IPPROTO_TCP;
7670Sstevel@tonic-gate #endif
7680Sstevel@tonic-gate #endif
7690Sstevel@tonic-gate
7700Sstevel@tonic-gate ret=setsockopt(s,opt,TCP_NODELAY,(char *)&on,sizeof(on));
7710Sstevel@tonic-gate #endif
7720Sstevel@tonic-gate return(ret == 0);
7730Sstevel@tonic-gate }
7740Sstevel@tonic-gate #endif
7750Sstevel@tonic-gate
BIO_socket_nbio(int s,int mode)7760Sstevel@tonic-gate int BIO_socket_nbio(int s, int mode)
7770Sstevel@tonic-gate {
7780Sstevel@tonic-gate int ret= -1;
7790Sstevel@tonic-gate int l;
7800Sstevel@tonic-gate
7810Sstevel@tonic-gate l=mode;
7820Sstevel@tonic-gate #ifdef FIONBIO
7830Sstevel@tonic-gate ret=BIO_socket_ioctl(s,FIONBIO,&l);
7840Sstevel@tonic-gate #endif
7850Sstevel@tonic-gate return(ret == 0);
7860Sstevel@tonic-gate }
787