b_sock.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:18k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* crypto/bio/b_sock.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3.  * All rights reserved.
  4.  *
  5.  * This package is an SSL implementation written
  6.  * by Eric Young (eay@cryptsoft.com).
  7.  * The implementation was written so as to conform with Netscapes SSL.
  8.  * 
  9.  * This library is free for commercial and non-commercial use as long as
  10.  * the following conditions are aheared to.  The following conditions
  11.  * apply to all code found in this distribution, be it the RC4, RSA,
  12.  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
  13.  * included with this distribution is covered by the same copyright terms
  14.  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15.  * 
  16.  * Copyright remains Eric Young's, and as such any Copyright notices in
  17.  * the code are not to be removed.
  18.  * If this package is used in a product, Eric Young should be given attribution
  19.  * as the author of the parts of the library used.
  20.  * This can be in the form of a textual message at program startup or
  21.  * in documentation (online or textual) provided with the package.
  22.  * 
  23.  * Redistribution and use in source and binary forms, with or without
  24.  * modification, are permitted provided that the following conditions
  25.  * are met:
  26.  * 1. Redistributions of source code must retain the copyright
  27.  *    notice, this list of conditions and the following disclaimer.
  28.  * 2. Redistributions in binary form must reproduce the above copyright
  29.  *    notice, this list of conditions and the following disclaimer in the
  30.  *    documentation and/or other materials provided with the distribution.
  31.  * 3. All advertising materials mentioning features or use of this software
  32.  *    must display the following acknowledgement:
  33.  *    "This product includes cryptographic software written by
  34.  *     Eric Young (eay@cryptsoft.com)"
  35.  *    The word 'cryptographic' can be left out if the rouines from the library
  36.  *    being used are not cryptographic related :-).
  37.  * 4. If you include any Windows specific code (or a derivative thereof) from 
  38.  *    the apps directory (application code) you must include an acknowledgement:
  39.  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40.  * 
  41.  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51.  * SUCH DAMAGE.
  52.  * 
  53.  * The licence and distribution terms for any publically available version or
  54.  * derivative of this code cannot be changed.  i.e. this code cannot simply be
  55.  * copied and put under another distribution licence
  56.  * [including the GNU Public Licence.]
  57.  */
  58. #include <stdio.h>
  59. #include <stdlib.h>
  60. #include <errno.h>
  61. #define USE_SOCKETS
  62. #include "cryptlib.h"
  63. #include <openssl/bio.h>
  64. #if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
  65. #include "netdb.h"
  66. #endif
  67. #ifndef OPENSSL_NO_SOCK
  68. #ifdef OPENSSL_SYS_WIN16
  69. #define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
  70. #else
  71. #define SOCKET_PROTOCOL IPPROTO_TCP
  72. #endif
  73. #ifdef SO_MAXCONN
  74. #define MAX_LISTEN  SO_MAXCONN
  75. #elif defined(SOMAXCONN)
  76. #define MAX_LISTEN  SOMAXCONN
  77. #else
  78. #define MAX_LISTEN  32
  79. #endif
  80. #if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
  81. static int wsa_init_done=0;
  82. #endif
  83. #if 0
  84. static unsigned long BIO_ghbn_hits=0L;
  85. static unsigned long BIO_ghbn_miss=0L;
  86. #define GHBN_NUM 4
  87. static struct ghbn_cache_st
  88. {
  89. char name[129];
  90. struct hostent *ent;
  91. unsigned long order;
  92. } ghbn_cache[GHBN_NUM];
  93. #endif
  94. static int get_ip(const char *str,unsigned char *ip);
  95. #if 0
  96. static void ghbn_free(struct hostent *a);
  97. static struct hostent *ghbn_dup(struct hostent *a);
  98. #endif
  99. int BIO_get_host_ip(const char *str, unsigned char *ip)
  100. {
  101. int i;
  102. int err = 1;
  103. int locked = 0;
  104. struct hostent *he;
  105. i=get_ip(str,ip);
  106. if (i < 0)
  107. {
  108. BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS);
  109. goto err;
  110. }
  111. /* At this point, we have something that is most probably correct
  112.    in some way, so let's init the socket. */
  113. if (BIO_sock_init() != 1)
  114. return 0; /* don't generate another error code here */
  115. /* If the string actually contained an IP address, we need not do
  116.    anything more */
  117. if (i > 0) return(1);
  118. /* do a gethostbyname */
  119. CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
  120. locked = 1;
  121. he=BIO_gethostbyname(str);
  122. if (he == NULL)
  123. {
  124. BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP);
  125. goto err;
  126. }
  127. /* cast to short because of win16 winsock definition */
  128. if ((short)he->h_addrtype != AF_INET)
  129. {
  130. BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
  131. goto err;
  132. }
  133. for (i=0; i<4; i++)
  134. ip[i]=he->h_addr_list[0][i];
  135. err = 0;
  136.  err:
  137. if (locked)
  138. CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
  139. if (err)
  140. {
  141. ERR_add_error_data(2,"host=",str);
  142. return 0;
  143. }
  144. else
  145. return 1;
  146. }
  147. int BIO_get_port(const char *str, unsigned short *port_ptr)
  148. {
  149. int i;
  150. struct servent *s;
  151. if (str == NULL)
  152. {
  153. BIOerr(BIO_F_BIO_GET_PORT,BIO_R_NO_PORT_DEFINED);
  154. return(0);
  155. }
  156. i=atoi(str);
  157. if (i != 0)
  158. *port_ptr=(unsigned short)i;
  159. else
  160. {
  161. CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
  162. /* Note: under VMS with SOCKETSHR, it seems like the first
  163.  * parameter is 'char *', instead of 'const char *'
  164.  */
  165.   s=getservbyname(
  166. #ifndef CONST_STRICT
  167.     (char *)
  168. #endif
  169.     str,"tcp");
  170. if(s != NULL)
  171. *port_ptr=ntohs((unsigned short)s->s_port);
  172. CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
  173. if(s == NULL)
  174. {
  175. if (strcmp(str,"http") == 0)
  176. *port_ptr=80;
  177. else if (strcmp(str,"telnet") == 0)
  178. *port_ptr=23;
  179. else if (strcmp(str,"socks") == 0)
  180. *port_ptr=1080;
  181. else if (strcmp(str,"https") == 0)
  182. *port_ptr=443;
  183. else if (strcmp(str,"ssl") == 0)
  184. *port_ptr=443;
  185. else if (strcmp(str,"ftp") == 0)
  186. *port_ptr=21;
  187. else if (strcmp(str,"gopher") == 0)
  188. *port_ptr=70;
  189. #if 0
  190. else if (strcmp(str,"wais") == 0)
  191. *port_ptr=21;
  192. #endif
  193. else
  194. {
  195. SYSerr(SYS_F_GETSERVBYNAME,get_last_socket_error());
  196. ERR_add_error_data(3,"service='",str,"'");
  197. return(0);
  198. }
  199. }
  200. }
  201. return(1);
  202. }
  203. int BIO_sock_error(int sock)
  204. {
  205. int j,i;
  206. int size;
  207.  
  208. size=sizeof(int);
  209. /* Note: under Windows the third parameter is of type (char *)
  210.  * whereas under other systems it is (void *) if you don't have
  211.  * a cast it will choke the compiler: if you do have a cast then
  212.  * you can either go for (char *) or (void *).
  213.  */
  214. i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void *)&j,(void *)&size);
  215. if (i < 0)
  216. return(1);
  217. else
  218. return(j);
  219. }
  220. #if 0
  221. long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
  222. {
  223. int i;
  224. char **p;
  225. switch (cmd)
  226. {
  227. case BIO_GHBN_CTRL_HITS:
  228. return(BIO_ghbn_hits);
  229. /* break; */
  230. case BIO_GHBN_CTRL_MISSES:
  231. return(BIO_ghbn_miss);
  232. /* break; */
  233. case BIO_GHBN_CTRL_CACHE_SIZE:
  234. return(GHBN_NUM);
  235. /* break; */
  236. case BIO_GHBN_CTRL_GET_ENTRY:
  237. if ((iarg >= 0) && (iarg <GHBN_NUM) &&
  238. (ghbn_cache[iarg].order > 0))
  239. {
  240. p=(char **)parg;
  241. if (p == NULL) return(0);
  242. *p=ghbn_cache[iarg].name;
  243. ghbn_cache[iarg].name[128]='';
  244. return(1);
  245. }
  246. return(0);
  247. /* break; */
  248. case BIO_GHBN_CTRL_FLUSH:
  249. for (i=0; i<GHBN_NUM; i++)
  250. ghbn_cache[i].order=0;
  251. break;
  252. default:
  253. return(0);
  254. }
  255. return(1);
  256. }
  257. #endif
  258. #if 0
  259. static struct hostent *ghbn_dup(struct hostent *a)
  260. {
  261. struct hostent *ret;
  262. int i,j;
  263. MemCheck_off();
  264. ret=(struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
  265. if (ret == NULL) return(NULL);
  266. memset(ret,0,sizeof(struct hostent));
  267. for (i=0; a->h_aliases[i] != NULL; i++)
  268. ;
  269. i++;
  270. ret->h_aliases = (char **)OPENSSL_malloc(i*sizeof(char *));
  271. if (ret->h_aliases == NULL)
  272. goto err;
  273. memset(ret->h_aliases, 0, i*sizeof(char *));
  274. for (i=0; a->h_addr_list[i] != NULL; i++)
  275. ;
  276. i++;
  277. ret->h_addr_list=(char **)OPENSSL_malloc(i*sizeof(char *));
  278. if (ret->h_addr_list == NULL)
  279. goto err;
  280. memset(ret->h_addr_list, 0, i*sizeof(char *));
  281. j=strlen(a->h_name)+1;
  282. if ((ret->h_name=OPENSSL_malloc(j)) == NULL) goto err;
  283. memcpy((char *)ret->h_name,a->h_name,j);
  284. for (i=0; a->h_aliases[i] != NULL; i++)
  285. {
  286. j=strlen(a->h_aliases[i])+1;
  287. if ((ret->h_aliases[i]=OPENSSL_malloc(j)) == NULL) goto err;
  288. memcpy(ret->h_aliases[i],a->h_aliases[i],j);
  289. }
  290. ret->h_length=a->h_length;
  291. ret->h_addrtype=a->h_addrtype;
  292. for (i=0; a->h_addr_list[i] != NULL; i++)
  293. {
  294. if ((ret->h_addr_list[i]=OPENSSL_malloc(a->h_length)) == NULL)
  295. goto err;
  296. memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length);
  297. }
  298. if (0)
  299. {
  300. err:
  301. if (ret != NULL)
  302. ghbn_free(ret);
  303. ret=NULL;
  304. }
  305. MemCheck_on();
  306. return(ret);
  307. }
  308. static void ghbn_free(struct hostent *a)
  309. {
  310. int i;
  311. if(a == NULL)
  312.     return;
  313. if (a->h_aliases != NULL)
  314. {
  315. for (i=0; a->h_aliases[i] != NULL; i++)
  316. OPENSSL_free(a->h_aliases[i]);
  317. OPENSSL_free(a->h_aliases);
  318. }
  319. if (a->h_addr_list != NULL)
  320. {
  321. for (i=0; a->h_addr_list[i] != NULL; i++)
  322. OPENSSL_free(a->h_addr_list[i]);
  323. OPENSSL_free(a->h_addr_list);
  324. }
  325. if (a->h_name != NULL) OPENSSL_free(a->h_name);
  326. OPENSSL_free(a);
  327. }
  328. #endif
  329. struct hostent *BIO_gethostbyname(const char *name)
  330. {
  331. #if 1
  332. /* Caching gethostbyname() results forever is wrong,
  333.  * so we have to let the true gethostbyname() worry about this */
  334. return gethostbyname(name);
  335. #else
  336. struct hostent *ret;
  337. int i,lowi=0,j;
  338. unsigned long low= (unsigned long)-1;
  339. #  if 0
  340. /* It doesn't make sense to use locking here: The function interface
  341.  * is not thread-safe, because threads can never be sure when
  342.  * some other thread destroys the data they were given a pointer to.
  343.  */
  344. CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
  345. #  endif
  346. j=strlen(name);
  347. if (j < 128)
  348. {
  349. for (i=0; i<GHBN_NUM; i++)
  350. {
  351. if (low > ghbn_cache[i].order)
  352. {
  353. low=ghbn_cache[i].order;
  354. lowi=i;
  355. }
  356. if (ghbn_cache[i].order > 0)
  357. {
  358. if (strncmp(name,ghbn_cache[i].name,128) == 0)
  359. break;
  360. }
  361. }
  362. }
  363. else
  364. i=GHBN_NUM;
  365. if (i == GHBN_NUM) /* no hit*/
  366. {
  367. BIO_ghbn_miss++;
  368. /* Note: under VMS with SOCKETSHR, it seems like the first
  369.  * parameter is 'char *', instead of 'const char *'
  370.  */
  371. ret=gethostbyname(
  372. #  ifndef CONST_STRICT
  373.     (char *)
  374. #  endif
  375.     name);
  376. if (ret == NULL)
  377. goto end;
  378. if (j > 128) /* too big to cache */
  379. {
  380. #  if 0
  381. /* If we were trying to make this function thread-safe (which
  382.  * is bound to fail), we'd have to give up in this case
  383.  * (or allocate more memory). */
  384. ret = NULL;
  385. #  endif
  386. goto end;
  387. }
  388. /* else add to cache */
  389. if (ghbn_cache[lowi].ent != NULL)
  390. ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
  391. ghbn_cache[lowi].name[0] = '';
  392. if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL)
  393. {
  394. BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE);
  395. goto end;
  396. }
  397. strncpy(ghbn_cache[lowi].name,name,128);
  398. ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits;
  399. }
  400. else
  401. {
  402. BIO_ghbn_hits++;
  403. ret= ghbn_cache[i].ent;
  404. ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits;
  405. }
  406. end:
  407. #  if 0
  408. CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
  409. #  endif
  410. return(ret);
  411. #endif
  412. }
  413. int BIO_sock_init(void)
  414. {
  415. #ifdef OPENSSL_SYS_WINDOWS
  416. static struct WSAData wsa_state;
  417. if (!wsa_init_done)
  418. {
  419. int err;
  420.   
  421. #ifdef SIGINT
  422. signal(SIGINT,(void (*)(int))BIO_sock_cleanup);
  423. #endif
  424. wsa_init_done=1;
  425. memset(&wsa_state,0,sizeof(wsa_state));
  426. if (WSAStartup(0x0101,&wsa_state)!=0)
  427. {
  428. err=WSAGetLastError();
  429. SYSerr(SYS_F_WSASTARTUP,err);
  430. BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
  431. return(-1);
  432. }
  433. }
  434. #endif /* OPENSSL_SYS_WINDOWS */
  435. #ifdef WATT32
  436. extern int _watt_do_exit;
  437. _watt_do_exit = 0;    /* don't make sock_init() call exit() */
  438. if (sock_init())
  439. return (-1);
  440. #endif
  441. #if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
  442.     WORD wVerReq;
  443.     WSADATA wsaData;
  444.     int err;
  445.     if (!wsa_init_done)
  446.     {
  447.    
  448. # ifdef SIGINT
  449.         signal(SIGINT,(void (*)(int))BIO_sock_cleanup);
  450. # endif
  451.         wsa_init_done=1;
  452.         wVerReq = MAKEWORD( 2, 0 );
  453.         err = WSAStartup(wVerReq,&wsaData);
  454.         if (err != 0)
  455.         {
  456.             SYSerr(SYS_F_WSASTARTUP,err);
  457.             BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
  458.             return(-1);
  459. }
  460. }
  461. #endif
  462. return(1);
  463. }
  464. void BIO_sock_cleanup(void)
  465. {
  466. #ifdef OPENSSL_SYS_WINDOWS
  467. if (wsa_init_done)
  468. {
  469. wsa_init_done=0;
  470. #ifndef OPENSSL_SYS_WINCE
  471. WSACancelBlockingCall();
  472. #endif
  473. WSACleanup();
  474. }
  475. #elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
  476.    if (wsa_init_done)
  477.         {
  478.         wsa_init_done=0;
  479.         WSACleanup();
  480. }
  481. #endif
  482. }
  483. #if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
  484. int BIO_socket_ioctl(int fd, long type, void *arg)
  485. {
  486. int i;
  487. #ifdef __DJGPP__
  488. i=ioctlsocket(fd,type,(char *)arg);
  489. #else
  490. i=ioctlsocket(fd,type,arg);
  491. #endif /* __DJGPP__ */
  492. if (i < 0)
  493. SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error());
  494. return(i);
  495. }
  496. #endif /* __VMS_VER */
  497. /* The reason I have implemented this instead of using sscanf is because
  498.  * Visual C 1.52c gives an unresolved external when linking a DLL :-( */
  499. static int get_ip(const char *str, unsigned char ip[4])
  500. {
  501. unsigned int tmp[4];
  502. int num=0,c,ok=0;
  503. tmp[0]=tmp[1]=tmp[2]=tmp[3]=0;
  504. for (;;)
  505. {
  506. c= *(str++);
  507. if ((c >= '0') && (c <= '9'))
  508. {
  509. ok=1;
  510. tmp[num]=tmp[num]*10+c-'0';
  511. if (tmp[num] > 255) return(0);
  512. }
  513. else if (c == '.')
  514. {
  515. if (!ok) return(-1);
  516. if (num == 3) return(0);
  517. num++;
  518. ok=0;
  519. }
  520. else if (c == '' && (num == 3) && ok)
  521. break;
  522. else
  523. return(0);
  524. }
  525. ip[0]=tmp[0];
  526. ip[1]=tmp[1];
  527. ip[2]=tmp[2];
  528. ip[3]=tmp[3];
  529. return(1);
  530. }
  531. int BIO_get_accept_socket(char *host, int bind_mode)
  532. {
  533. int ret=0;
  534. struct sockaddr_in server,client;
  535. int s=INVALID_SOCKET,cs;
  536. unsigned char ip[4];
  537. unsigned short port;
  538. char *str=NULL,*e;
  539. const char *h,*p;
  540. unsigned long l;
  541. int err_num;
  542. if (BIO_sock_init() != 1) return(INVALID_SOCKET);
  543. if ((str=BUF_strdup(host)) == NULL) return(INVALID_SOCKET);
  544. h=p=NULL;
  545. h=str;
  546. for (e=str; *e; e++)
  547. {
  548. if (*e == ':')
  549. {
  550. p= &(e[1]);
  551. *e='';
  552. }
  553. else if (*e == '/')
  554. {
  555. *e='';
  556. break;
  557. }
  558. }
  559. if (p == NULL)
  560. {
  561. p=h;
  562. h="*";
  563. }
  564. if (!BIO_get_port(p,&port)) goto err;
  565. memset((char *)&server,0,sizeof(server));
  566. server.sin_family=AF_INET;
  567. server.sin_port=htons(port);
  568. if (strcmp(h,"*") == 0)
  569. server.sin_addr.s_addr=INADDR_ANY;
  570. else
  571. {
  572.                 if (!BIO_get_host_ip(h,&(ip[0]))) goto err;
  573. l=(unsigned long)
  574. ((unsigned long)ip[0]<<24L)|
  575. ((unsigned long)ip[1]<<16L)|
  576. ((unsigned long)ip[2]<< 8L)|
  577. ((unsigned long)ip[3]);
  578. server.sin_addr.s_addr=htonl(l);
  579. }
  580. again:
  581. s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
  582. if (s == INVALID_SOCKET)
  583. {
  584. SYSerr(SYS_F_SOCKET,get_last_socket_error());
  585. ERR_add_error_data(3,"port='",host,"'");
  586. BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET);
  587. goto err;
  588. }
  589. #ifdef SO_REUSEADDR
  590. if (bind_mode == BIO_BIND_REUSEADDR)
  591. {
  592. int i=1;
  593. ret=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i));
  594. bind_mode=BIO_BIND_NORMAL;
  595. }
  596. #endif
  597. if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
  598. {
  599. #ifdef SO_REUSEADDR
  600. err_num=get_last_socket_error();
  601. if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
  602. (err_num == EADDRINUSE))
  603. {
  604. memcpy((char *)&client,(char *)&server,sizeof(server));
  605. if (strcmp(h,"*") == 0)
  606. client.sin_addr.s_addr=htonl(0x7F000001);
  607. cs=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
  608. if (cs != INVALID_SOCKET)
  609. {
  610. int ii;
  611. ii=connect(cs,(struct sockaddr *)&client,
  612. sizeof(client));
  613. closesocket(cs);
  614. if (ii == INVALID_SOCKET)
  615. {
  616. bind_mode=BIO_BIND_REUSEADDR;
  617. closesocket(s);
  618. goto again;
  619. }
  620. /* else error */
  621. }
  622. /* else error */
  623. }
  624. #endif
  625. SYSerr(SYS_F_BIND,err_num);
  626. ERR_add_error_data(3,"port='",host,"'");
  627. BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET);
  628. goto err;
  629. }
  630. if (listen(s,MAX_LISTEN) == -1)
  631. {
  632. SYSerr(SYS_F_BIND,get_last_socket_error());
  633. ERR_add_error_data(3,"port='",host,"'");
  634. BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_LISTEN_SOCKET);
  635. goto err;
  636. }
  637. ret=1;
  638. err:
  639. if (str != NULL) OPENSSL_free(str);
  640. if ((ret == 0) && (s != INVALID_SOCKET))
  641. {
  642. closesocket(s);
  643. s= INVALID_SOCKET;
  644. }
  645. return(s);
  646. }
  647. int BIO_accept(int sock, char **addr)
  648. {
  649. int ret=INVALID_SOCKET;
  650. static struct sockaddr_in from;
  651. unsigned long l;
  652. unsigned short port;
  653. int len;
  654. char *p;
  655. memset((char *)&from,0,sizeof(from));
  656. len=sizeof(from);
  657. /* Note: under VMS with SOCKETSHR the fourth parameter is currently
  658.  * of type (int *) whereas under other systems it is (void *) if
  659.  * you don't have a cast it will choke the compiler: if you do
  660.  * have a cast then you can either go for (int *) or (void *).
  661.  */
  662. ret=accept(sock,(struct sockaddr *)&from,(void *)&len);
  663. if (ret == INVALID_SOCKET)
  664. {
  665. if(BIO_sock_should_retry(ret)) return -2;
  666. SYSerr(SYS_F_ACCEPT,get_last_socket_error());
  667. BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR);
  668. goto end;
  669. }
  670. if (addr == NULL) goto end;
  671. l=ntohl(from.sin_addr.s_addr);
  672. port=ntohs(from.sin_port);
  673. if (*addr == NULL)
  674. {
  675. if ((p=OPENSSL_malloc(24)) == NULL)
  676. {
  677. BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
  678. goto end;
  679. }
  680. *addr=p;
  681. }
  682. BIO_snprintf(*addr,24,"%d.%d.%d.%d:%d",
  683.      (unsigned char)(l>>24L)&0xff,
  684.      (unsigned char)(l>>16L)&0xff,
  685.      (unsigned char)(l>> 8L)&0xff,
  686.      (unsigned char)(l     )&0xff,
  687.      port);
  688. end:
  689. return(ret);
  690. }
  691. int BIO_set_tcp_ndelay(int s, int on)
  692. {
  693. int ret=0;
  694. #if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
  695. int opt;
  696. #ifdef SOL_TCP
  697. opt=SOL_TCP;
  698. #else
  699. #ifdef IPPROTO_TCP
  700. opt=IPPROTO_TCP;
  701. #endif
  702. #endif
  703. ret=setsockopt(s,opt,TCP_NODELAY,(char *)&on,sizeof(on));
  704. #endif
  705. return(ret == 0);
  706. }
  707. #endif
  708. int BIO_socket_nbio(int s, int mode)
  709. {
  710. int ret= -1;
  711. int l;
  712. l=mode;
  713. #ifdef FIONBIO
  714. ret=BIO_socket_ioctl(s,FIONBIO,&l);
  715. #endif
  716. return(ret == 0);
  717. }