b_sock.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  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. #ifndef OPENSSL_NO_SOCK
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <errno.h>
  62. #define USE_SOCKETS
  63. #include "cryptlib.h"
  64. #include <openssl/bio.h>
  65. #ifdef OPENSSL_SYS_WIN16
  66. #define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
  67. #else
  68. #define SOCKET_PROTOCOL IPPROTO_TCP
  69. #endif
  70. #ifdef SO_MAXCONN
  71. #define MAX_LISTEN SOMAXCONN
  72. #elif defined(SO_MAXCONN)
  73. #define MAX_LISTEN SO_MAXCONN
  74. #else
  75. #define MAX_LISTEN 32
  76. #endif
  77. #ifdef OPENSSL_SYS_WINDOWS
  78. static int wsa_init_done=0;
  79. #endif
  80. static unsigned long BIO_ghbn_hits=0L;
  81. static unsigned long BIO_ghbn_miss=0L;
  82. #define GHBN_NUM 4
  83. static struct ghbn_cache_st
  84. {
  85. char name[129];
  86. struct hostent *ent;
  87. unsigned long order;
  88. } ghbn_cache[GHBN_NUM];
  89. static int get_ip(const char *str,unsigned char *ip);
  90. static void ghbn_free(struct hostent *a);
  91. static struct hostent *ghbn_dup(struct hostent *a);
  92. int BIO_get_host_ip(const char *str, unsigned char *ip)
  93. {
  94. int i;
  95. int err = 1;
  96. int locked = 0;
  97. struct hostent *he;
  98. i=get_ip(str,ip);
  99. if (i < 0)
  100. {
  101. BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS);
  102. goto err;
  103. }
  104. /* At this point, we have something that is most probably correct
  105. in some way, so let's init the socket. */
  106. if (BIO_sock_init() != 1)
  107. return 0; /* don't generate another error code here */
  108. /* If the string actually contained an IP address, we need not do
  109. anything more */
  110. if (i > 0) return(1);
  111. /* do a gethostbyname */
  112. CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
  113. locked = 1;
  114. he=BIO_gethostbyname(str);
  115. if (he == NULL)
  116. {
  117. BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP);
  118. goto err;
  119. }
  120. /* cast to short because of win16 winsock definition */
  121. if ((short)he->h_addrtype != AF_INET)
  122. {
  123. BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
  124. goto err;
  125. }
  126. for (i=0; i<4; i++)
  127. ip[i]=he->h_addr_list[0][i];
  128. err = 0;
  129. err:
  130. if (locked)
  131. CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
  132. if (err)
  133. {
  134. ERR_add_error_data(2,"host=",str);
  135. return 0;
  136. }
  137. else
  138. return 1;
  139. }
  140. int BIO_get_port(const char *str, unsigned short *port_ptr)
  141. {
  142. int i;
  143. struct servent *s;
  144. if (str == NULL)
  145. {
  146. BIOerr(BIO_F_BIO_GET_PORT,BIO_R_NO_PORT_DEFINED);
  147. return(0);
  148. }
  149. i=atoi(str);
  150. if (i != 0)
  151. *port_ptr=(unsigned short)i;
  152. else
  153. {
  154. CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
  155. /* Note: under VMS with SOCKETSHR, it seems like the first
  156. * parameter is 'char *', instead of 'const char *'
  157. */
  158. s=getservbyname(
  159. #ifndef CONST_STRICT
  160. (char *)
  161. #endif
  162. str,"tcp");
  163. if(s != NULL)
  164. *port_ptr=ntohs((unsigned short)s->s_port);
  165. CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
  166. if(s == NULL)
  167. {
  168. if (strcmp(str,"http") == 0)
  169. *port_ptr=80;
  170. else if (strcmp(str,"telnet") == 0)
  171. *port_ptr=23;
  172. else if (strcmp(str,"socks") == 0)
  173. *port_ptr=1080;
  174. else if (strcmp(str,"https") == 0)
  175. *port_ptr=443;
  176. else if (strcmp(str,"ssl") == 0)
  177. *port_ptr=443;
  178. else if (strcmp(str,"ftp") == 0)
  179. *port_ptr=21;
  180. else if (strcmp(str,"gopher") == 0)
  181. *port_ptr=70;
  182. #if 0
  183. else if (strcmp(str,"wais") == 0)
  184. *port_ptr=21;
  185. #endif
  186. else
  187. {
  188. SYSerr(SYS_F_GETSERVBYNAME,get_last_socket_error());
  189. ERR_add_error_data(3,"service='",str,"'");
  190. return(0);
  191. }
  192. }
  193. }
  194. return(1);
  195. }
  196. int BIO_sock_error(int sock)
  197. {
  198. int j,i;
  199. int size;
  200. size=sizeof(int);
  201. /* Note: under Windows the third parameter is of type (char *)
  202. * whereas under other systems it is (void *) if you don't have
  203. * a cast it will choke the compiler: if you do have a cast then
  204. * you can either go for (char *) or (void *).
  205. */
  206. i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void *)&j,(void *)&size);
  207. if (i < 0)
  208. return(1);
  209. else
  210. return(j);
  211. }
  212. long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
  213. {
  214. int i;
  215. char **p;
  216. switch (cmd)
  217. {
  218. case BIO_GHBN_CTRL_HITS:
  219. return(BIO_ghbn_hits);
  220. /* break; */
  221. case BIO_GHBN_CTRL_MISSES:
  222. return(BIO_ghbn_miss);
  223. /* break; */
  224. case BIO_GHBN_CTRL_CACHE_SIZE:
  225. return(GHBN_NUM);
  226. /* break; */
  227. case BIO_GHBN_CTRL_GET_ENTRY:
  228. if ((iarg >= 0) && (iarg <GHBN_NUM) &&
  229. (ghbn_cache[iarg].order > 0))
  230. {
  231. p=(char **)parg;
  232. if (p == NULL) return(0);
  233. *p=ghbn_cache[iarg].name;
  234. ghbn_cache[iarg].name[128]='\0';
  235. return(1);
  236. }
  237. return(0);
  238. /* break; */
  239. case BIO_GHBN_CTRL_FLUSH:
  240. for (i=0; i<GHBN_NUM; i++)
  241. ghbn_cache[i].order=0;
  242. break;
  243. default:
  244. return(0);
  245. }
  246. return(1);
  247. }
  248. static struct hostent *ghbn_dup(struct hostent *a)
  249. {
  250. struct hostent *ret;
  251. int i,j;
  252. MemCheck_off();
  253. ret=(struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
  254. if (ret == NULL) return(NULL);
  255. memset(ret,0,sizeof(struct hostent));
  256. for (i=0; a->h_aliases[i] != NULL; i++)
  257. ;
  258. i++;
  259. ret->h_aliases = (char **)OPENSSL_malloc(i*sizeof(char *));
  260. if (ret->h_aliases == NULL)
  261. goto err;
  262. memset(ret->h_aliases, 0, i*sizeof(char *));
  263. for (i=0; a->h_addr_list[i] != NULL; i++)
  264. ;
  265. i++;
  266. ret->h_addr_list=(char **)OPENSSL_malloc(i*sizeof(char *));
  267. if (ret->h_addr_list == NULL)
  268. goto err;
  269. memset(ret->h_addr_list, 0, i*sizeof(char *));
  270. j=strlen(a->h_name)+1;
  271. if ((ret->h_name=OPENSSL_malloc(j)) == NULL) goto err;
  272. memcpy((char *)ret->h_name,a->h_name,j);
  273. for (i=0; a->h_aliases[i] != NULL; i++)
  274. {
  275. j=strlen(a->h_aliases[i])+1;
  276. if ((ret->h_aliases[i]=OPENSSL_malloc(j)) == NULL) goto err;
  277. memcpy(ret->h_aliases[i],a->h_aliases[i],j);
  278. }
  279. ret->h_length=a->h_length;
  280. ret->h_addrtype=a->h_addrtype;
  281. for (i=0; a->h_addr_list[i] != NULL; i++)
  282. {
  283. if ((ret->h_addr_list[i]=OPENSSL_malloc(a->h_length)) == NULL)
  284. goto err;
  285. memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length);
  286. }
  287. if (0)
  288. {
  289. err:
  290. if (ret != NULL)
  291. ghbn_free(ret);
  292. ret=NULL;
  293. }
  294. MemCheck_on();
  295. return(ret);
  296. }
  297. static void ghbn_free(struct hostent *a)
  298. {
  299. int i;
  300. if(a == NULL)
  301. return;
  302. if (a->h_aliases != NULL)
  303. {
  304. for (i=0; a->h_aliases[i] != NULL; i++)
  305. OPENSSL_free(a->h_aliases[i]);
  306. OPENSSL_free(a->h_aliases);
  307. }
  308. if (a->h_addr_list != NULL)
  309. {
  310. for (i=0; a->h_addr_list[i] != NULL; i++)
  311. OPENSSL_free(a->h_addr_list[i]);
  312. OPENSSL_free(a->h_addr_list);
  313. }
  314. if (a->h_name != NULL) OPENSSL_free(a->h_name);
  315. OPENSSL_free(a);
  316. }
  317. struct hostent *BIO_gethostbyname(const char *name)
  318. {
  319. struct hostent *ret;
  320. int i,lowi=0,j;
  321. unsigned long low= (unsigned long)-1;
  322. /* return(gethostbyname(name)); */
  323. #if 0 /* It doesn't make sense to use locking here: The function interface
  324. * is not thread-safe, because threads can never be sure when
  325. * some other thread destroys the data they were given a pointer to.
  326. */
  327. CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
  328. #endif
  329. j=strlen(name);
  330. if (j < 128)
  331. {
  332. for (i=0; i<GHBN_NUM; i++)
  333. {
  334. if (low > ghbn_cache[i].order)
  335. {
  336. low=ghbn_cache[i].order;
  337. lowi=i;
  338. }
  339. if (ghbn_cache[i].order > 0)
  340. {
  341. if (strncmp(name,ghbn_cache[i].name,128) == 0)
  342. break;
  343. }
  344. }
  345. }
  346. else
  347. i=GHBN_NUM;
  348. if (i == GHBN_NUM) /* no hit*/
  349. {
  350. BIO_ghbn_miss++;
  351. /* Note: under VMS with SOCKETSHR, it seems like the first
  352. * parameter is 'char *', instead of 'const char *'
  353. */
  354. ret=gethostbyname(
  355. #ifndef CONST_STRICT
  356. (char *)
  357. #endif
  358. name);
  359. if (ret == NULL)
  360. goto end;
  361. if (j > 128) /* too big to cache */
  362. {
  363. #if 0 /* If we were trying to make this function thread-safe (which
  364. * is bound to fail), we'd have to give up in this case
  365. * (or allocate more memory). */
  366. ret = NULL;
  367. #endif
  368. goto end;
  369. }
  370. /* else add to cache */
  371. if (ghbn_cache[lowi].ent != NULL)
  372. ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
  373. ghbn_cache[lowi].name[0] = '\0';
  374. if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL)
  375. {
  376. BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE);
  377. goto end;
  378. }
  379. strncpy(ghbn_cache[lowi].name,name,128);
  380. ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits;
  381. }
  382. else
  383. {
  384. BIO_ghbn_hits++;
  385. ret= ghbn_cache[i].ent;
  386. ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits;
  387. }
  388. end:
  389. #if 0
  390. CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
  391. #endif
  392. return(ret);
  393. }
  394. int BIO_sock_init(void)
  395. {
  396. #ifdef OPENSSL_SYS_WINDOWS
  397. static struct WSAData wsa_state;
  398. if (!wsa_init_done)
  399. {
  400. int err;
  401. #ifdef SIGINT
  402. signal(SIGINT,(void (*)(int))BIO_sock_cleanup);
  403. #endif
  404. wsa_init_done=1;
  405. memset(&wsa_state,0,sizeof(wsa_state));
  406. if (WSAStartup(0x0101,&wsa_state)!=0)
  407. {
  408. err=WSAGetLastError();
  409. SYSerr(SYS_F_WSASTARTUP,err);
  410. BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
  411. return(-1);
  412. }
  413. }
  414. #endif /* OPENSSL_SYS_WINDOWS */
  415. return(1);
  416. }
  417. void BIO_sock_cleanup(void)
  418. {
  419. #ifdef OPENSSL_SYS_WINDOWS
  420. if (wsa_init_done)
  421. {
  422. wsa_init_done=0;
  423. WSACancelBlockingCall();
  424. WSACleanup();
  425. }
  426. #endif
  427. }
  428. #if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
  429. int BIO_socket_ioctl(int fd, long type, unsigned long *arg)
  430. {
  431. int i;
  432. i=ioctlsocket(fd,type,arg);
  433. if (i < 0)
  434. SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error());
  435. return(i);
  436. }
  437. #endif /* __VMS_VER */
  438. /* The reason I have implemented this instead of using sscanf is because
  439. * Visual C 1.52c gives an unresolved external when linking a DLL :-( */
  440. static int get_ip(const char *str, unsigned char ip[4])
  441. {
  442. unsigned int tmp[4];
  443. int num=0,c,ok=0;
  444. tmp[0]=tmp[1]=tmp[2]=tmp[3]=0;
  445. for (;;)
  446. {
  447. c= *(str++);
  448. if ((c >= '0') && (c <= '9'))
  449. {
  450. ok=1;
  451. tmp[num]=tmp[num]*10+c-'0';
  452. if (tmp[num] > 255) return(-1);
  453. }
  454. else if (c == '.')
  455. {
  456. if (!ok) return(-1);
  457. if (num == 3) break;
  458. num++;
  459. ok=0;
  460. }
  461. else if ((num == 3) && ok)
  462. break;
  463. else
  464. return(0);
  465. }
  466. ip[0]=tmp[0];
  467. ip[1]=tmp[1];
  468. ip[2]=tmp[2];
  469. ip[3]=tmp[3];
  470. return(1);
  471. }
  472. int BIO_get_accept_socket(char *host, int bind_mode)
  473. {
  474. int ret=0;
  475. struct sockaddr_in server,client;
  476. int s=INVALID_SOCKET,cs;
  477. unsigned char ip[4];
  478. unsigned short port;
  479. char *str=NULL,*e;
  480. const char *h,*p;
  481. unsigned long l;
  482. int err_num;
  483. if (BIO_sock_init() != 1) return(INVALID_SOCKET);
  484. if ((str=BUF_strdup(host)) == NULL) return(INVALID_SOCKET);
  485. h=p=NULL;
  486. h=str;
  487. for (e=str; *e; e++)
  488. {
  489. if (*e == ':')
  490. {
  491. p= &(e[1]);
  492. *e='\0';
  493. }
  494. else if (*e == '/')
  495. {
  496. *e='\0';
  497. break;
  498. }
  499. }
  500. if (p == NULL)
  501. {
  502. p=h;
  503. h="*";
  504. }
  505. if (!BIO_get_port(p,&port)) goto err;
  506. memset((char *)&server,0,sizeof(server));
  507. server.sin_family=AF_INET;
  508. server.sin_port=htons(port);
  509. if (strcmp(h,"*") == 0)
  510. server.sin_addr.s_addr=INADDR_ANY;
  511. else
  512. {
  513. if (!BIO_get_host_ip(h,&(ip[0]))) goto err;
  514. l=(unsigned long)
  515. ((unsigned long)ip[0]<<24L)|
  516. ((unsigned long)ip[1]<<16L)|
  517. ((unsigned long)ip[2]<< 8L)|
  518. ((unsigned long)ip[3]);
  519. server.sin_addr.s_addr=htonl(l);
  520. }
  521. again:
  522. s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
  523. if (s == INVALID_SOCKET)
  524. {
  525. SYSerr(SYS_F_SOCKET,get_last_socket_error());
  526. ERR_add_error_data(3,"port='",host,"'");
  527. BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET);
  528. goto err;
  529. }
  530. #ifdef SO_REUSEADDR
  531. if (bind_mode == BIO_BIND_REUSEADDR)
  532. {
  533. int i=1;
  534. ret=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i));
  535. bind_mode=BIO_BIND_NORMAL;
  536. }
  537. #endif
  538. if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
  539. {
  540. #ifdef SO_REUSEADDR
  541. err_num=get_last_socket_error();
  542. if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
  543. (err_num == EADDRINUSE))
  544. {
  545. memcpy((char *)&client,(char *)&server,sizeof(server));
  546. if (strcmp(h,"*") == 0)
  547. client.sin_addr.s_addr=htonl(0x7F000001);
  548. cs=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
  549. if (cs != INVALID_SOCKET)
  550. {
  551. int ii;
  552. ii=connect(cs,(struct sockaddr *)&client,
  553. sizeof(client));
  554. closesocket(cs);
  555. if (ii == INVALID_SOCKET)
  556. {
  557. bind_mode=BIO_BIND_REUSEADDR;
  558. closesocket(s);
  559. goto again;
  560. }
  561. /* else error */
  562. }
  563. /* else error */
  564. }
  565. #endif
  566. SYSerr(SYS_F_BIND,err_num);
  567. ERR_add_error_data(3,"port='",host,"'");
  568. BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET);
  569. goto err;
  570. }
  571. if (listen(s,MAX_LISTEN) == -1)
  572. {
  573. SYSerr(SYS_F_BIND,get_last_socket_error());
  574. ERR_add_error_data(3,"port='",host,"'");
  575. BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_LISTEN_SOCKET);
  576. goto err;
  577. }
  578. ret=1;
  579. err:
  580. if (str != NULL) OPENSSL_free(str);
  581. if ((ret == 0) && (s != INVALID_SOCKET))
  582. {
  583. closesocket(s);
  584. s= INVALID_SOCKET;
  585. }
  586. return(s);
  587. }
  588. int BIO_accept(int sock, char **addr)
  589. {
  590. int ret=INVALID_SOCKET;
  591. static struct sockaddr_in from;
  592. unsigned long l;
  593. unsigned short port;
  594. int len;
  595. char *p;
  596. memset((char *)&from,0,sizeof(from));
  597. len=sizeof(from);
  598. /* Note: under VMS with SOCKETSHR the fourth parameter is currently
  599. * of type (int *) whereas under other systems it is (void *) if
  600. * you don't have a cast it will choke the compiler: if you do
  601. * have a cast then you can either go for (int *) or (void *).
  602. */
  603. ret=accept(sock,(struct sockaddr *)&from,(void *)&len);
  604. if (ret == INVALID_SOCKET)
  605. {
  606. if(BIO_sock_should_retry(ret)) return -2;
  607. SYSerr(SYS_F_ACCEPT,get_last_socket_error());
  608. BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR);
  609. goto end;
  610. }
  611. if (addr == NULL) goto end;
  612. l=ntohl(from.sin_addr.s_addr);
  613. port=ntohs(from.sin_port);
  614. if (*addr == NULL)
  615. {
  616. if ((p=OPENSSL_malloc(24)) == NULL)
  617. {
  618. BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
  619. goto end;
  620. }
  621. *addr=p;
  622. }
  623. sprintf(*addr,"%d.%d.%d.%d:%d",
  624. (unsigned char)(l>>24L)&0xff,
  625. (unsigned char)(l>>16L)&0xff,
  626. (unsigned char)(l>> 8L)&0xff,
  627. (unsigned char)(l )&0xff,
  628. port);
  629. end:
  630. return(ret);
  631. }
  632. int BIO_set_tcp_ndelay(int s, int on)
  633. {
  634. int ret=0;
  635. #if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
  636. int opt;
  637. #ifdef SOL_TCP
  638. opt=SOL_TCP;
  639. #else
  640. #ifdef IPPROTO_TCP
  641. opt=IPPROTO_TCP;
  642. #endif
  643. #endif
  644. ret=setsockopt(s,opt,TCP_NODELAY,(char *)&on,sizeof(on));
  645. #endif
  646. return(ret == 0);
  647. }
  648. #endif
  649. int BIO_socket_nbio(int s, int mode)
  650. {
  651. int ret= -1;
  652. unsigned long l;
  653. l=mode;
  654. #ifdef FIONBIO
  655. ret=BIO_socket_ioctl(s,FIONBIO,&l);
  656. #endif
  657. return(ret == 0);
  658. }