summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bio/b_sock.c
diff options
context:
space:
mode:
authorbeck <>1999-09-29 04:37:45 +0000
committerbeck <>1999-09-29 04:37:45 +0000
commitde8f24ea083384bb66b32ec105dc4743c5663cdf (patch)
tree1412176ae62a3cab2cf2b0b92150fcbceaac6092 /src/lib/libcrypto/bio/b_sock.c
parentcb929d29896bcb87c2a97417fbd03e50078fc178 (diff)
downloadopenbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.tar.gz
openbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.tar.bz2
openbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.zip
OpenSSL 0.9.4 merge
Diffstat (limited to 'src/lib/libcrypto/bio/b_sock.c')
-rw-r--r--src/lib/libcrypto/bio/b_sock.c319
1 files changed, 197 insertions, 122 deletions
diff --git a/src/lib/libcrypto/bio/b_sock.c b/src/lib/libcrypto/bio/b_sock.c
index a45909527c..d29b29ff8b 100644
--- a/src/lib/libcrypto/bio/b_sock.c
+++ b/src/lib/libcrypto/bio/b_sock.c
@@ -63,9 +63,7 @@
63#include <errno.h> 63#include <errno.h>
64#define USE_SOCKETS 64#define USE_SOCKETS
65#include "cryptlib.h" 65#include "cryptlib.h"
66#include "bio.h" 66#include <openssl/bio.h>
67
68/* BIOerr(BIO_F_WSASTARTUP,BIO_R_WSASTARTUP ); */
69 67
70#ifdef WIN16 68#ifdef WIN16
71#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ 69#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
@@ -96,21 +94,14 @@ static struct ghbn_cache_st
96 unsigned long order; 94 unsigned long order;
97 } ghbn_cache[GHBN_NUM]; 95 } ghbn_cache[GHBN_NUM];
98 96
99#ifndef NOPROTO 97static int get_ip(const char *str,unsigned char *ip);
100static int get_ip(char *str,unsigned char *ip);
101static void ghbn_free(struct hostent *a); 98static void ghbn_free(struct hostent *a);
102static struct hostent *ghbn_dup(struct hostent *a); 99static struct hostent *ghbn_dup(struct hostent *a);
103#else 100int BIO_get_host_ip(const char *str, unsigned char *ip)
104static int get_ip();
105static void ghbn_free();
106static struct hostent *ghbn_dup();
107#endif
108
109int BIO_get_host_ip(str,ip)
110char *str;
111unsigned char *ip;
112 { 101 {
113 int i; 102 int i;
103 int err = 1;
104 int locked = 0;
114 struct hostent *he; 105 struct hostent *he;
115 106
116 i=get_ip(str,ip); 107 i=get_ip(str,ip);
@@ -118,37 +109,45 @@ unsigned char *ip;
118 if (i < 0) 109 if (i < 0)
119 { 110 {
120 BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS); 111 BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS);
121 ERR_add_error_data(2,"host=",str); 112 goto err;
122 return(0);
123 } 113 }
124 else
125 { /* do a gethostbyname */
126 if (!BIO_sock_init()) return(0);
127 114
128 he=BIO_gethostbyname(str); 115 /* do a gethostbyname */
129 if (he == NULL) 116 if (!BIO_sock_init())
130 { 117 return(0); /* don't generate another error code here */
131 BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP);
132 ERR_add_error_data(2,"host=",str);
133 return(0);
134 }
135 118
136 /* cast to short because of win16 winsock definition */ 119 CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
137 if ((short)he->h_addrtype != AF_INET) 120 locked = 1;
138 { 121 he=BIO_gethostbyname(str);
139 BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET); 122 if (he == NULL)
140 ERR_add_error_data(2,"host=",str); 123 {
141 return(0); 124 BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP);
142 } 125 goto err;
143 for (i=0; i<4; i++)
144 ip[i]=he->h_addr_list[0][i];
145 } 126 }
146 return(1); 127
128 /* cast to short because of win16 winsock definition */
129 if ((short)he->h_addrtype != AF_INET)
130 {
131 BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
132 goto err;
133 }
134 for (i=0; i<4; i++)
135 ip[i]=he->h_addr_list[0][i];
136 err = 0;
137
138 err:
139 if (locked)
140 CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
141 if (err)
142 {
143 ERR_add_error_data(2,"host=",str);
144 return 0;
145 }
146 else
147 return 1;
147 } 148 }
148 149
149int BIO_get_port(str,port_ptr) 150int BIO_get_port(const char *str, unsigned short *port_ptr)
150char *str;
151short *port_ptr;
152 { 151 {
153 int i; 152 int i;
154 struct servent *s; 153 struct servent *s;
@@ -163,8 +162,12 @@ short *port_ptr;
163 *port_ptr=(unsigned short)i; 162 *port_ptr=(unsigned short)i;
164 else 163 else
165 { 164 {
166 s=getservbyname(str,"tcp"); 165 CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
167 if (s == NULL) 166 s=getservbyname(str,"tcp");
167 if(s != NULL)
168 *port_ptr=ntohs((unsigned short)s->s_port);
169 CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
170 if(s == NULL)
168 { 171 {
169 if (strcmp(str,"http") == 0) 172 if (strcmp(str,"http") == 0)
170 *port_ptr=80; 173 *port_ptr=80;
@@ -190,31 +193,30 @@ short *port_ptr;
190 ERR_add_error_data(3,"service='",str,"'"); 193 ERR_add_error_data(3,"service='",str,"'");
191 return(0); 194 return(0);
192 } 195 }
193 return(1);
194 } 196 }
195 *port_ptr=htons((unsigned short)s->s_port);
196 } 197 }
197 return(1); 198 return(1);
198 } 199 }
199 200
200int BIO_sock_error(sock) 201int BIO_sock_error(int sock)
201int sock;
202 { 202 {
203 int j,i,size; 203 int j,i;
204 int size;
204 205
205 size=sizeof(int); 206 size=sizeof(int);
206 207 /* Note: under Windows the third parameter is of type (char *)
207 i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(char *)&j,&size); 208 * whereas under other systems it is (void *) if you don't have
209 * a cast it will choke the compiler: if you do have a cast then
210 * you can either go for (char *) or (void *).
211 */
212 i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void *)&j,(void *)&size);
208 if (i < 0) 213 if (i < 0)
209 return(1); 214 return(1);
210 else 215 else
211 return(j); 216 return(j);
212 } 217 }
213 218
214long BIO_ghbn_ctrl(cmd,iarg,parg) 219long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
215int cmd;
216int iarg;
217char *parg;
218 { 220 {
219 int i; 221 int i;
220 char **p; 222 char **p;
@@ -223,13 +225,13 @@ char *parg;
223 { 225 {
224 case BIO_GHBN_CTRL_HITS: 226 case BIO_GHBN_CTRL_HITS:
225 return(BIO_ghbn_hits); 227 return(BIO_ghbn_hits);
226 break; 228 /* break; */
227 case BIO_GHBN_CTRL_MISSES: 229 case BIO_GHBN_CTRL_MISSES:
228 return(BIO_ghbn_miss); 230 return(BIO_ghbn_miss);
229 break; 231 /* break; */
230 case BIO_GHBN_CTRL_CACHE_SIZE: 232 case BIO_GHBN_CTRL_CACHE_SIZE:
231 return(GHBN_NUM); 233 return(GHBN_NUM);
232 break; 234 /* break; */
233 case BIO_GHBN_CTRL_GET_ENTRY: 235 case BIO_GHBN_CTRL_GET_ENTRY:
234 if ((iarg >= 0) && (iarg <GHBN_NUM) && 236 if ((iarg >= 0) && (iarg <GHBN_NUM) &&
235 (ghbn_cache[iarg].order > 0)) 237 (ghbn_cache[iarg].order > 0))
@@ -241,7 +243,7 @@ char *parg;
241 return(1); 243 return(1);
242 } 244 }
243 return(0); 245 return(0);
244 break; 246 /* break; */
245 case BIO_GHBN_CTRL_FLUSH: 247 case BIO_GHBN_CTRL_FLUSH:
246 for (i=0; i<GHBN_NUM; i++) 248 for (i=0; i<GHBN_NUM; i++)
247 ghbn_cache[i].order=0; 249 ghbn_cache[i].order=0;
@@ -252,77 +254,84 @@ char *parg;
252 return(1); 254 return(1);
253 } 255 }
254 256
255static struct hostent *ghbn_dup(a) 257static struct hostent *ghbn_dup(struct hostent *a)
256struct hostent *a;
257 { 258 {
258 struct hostent *ret; 259 struct hostent *ret;
259 int i,j; 260 int i,j;
260 261
261 ret=(struct hostent *)malloc(sizeof(struct hostent)); 262 MemCheck_off();
263 ret=(struct hostent *)Malloc(sizeof(struct hostent));
262 if (ret == NULL) return(NULL); 264 if (ret == NULL) return(NULL);
263 memset(ret,0,sizeof(struct hostent)); 265 memset(ret,0,sizeof(struct hostent));
264 266
265 for (i=0; a->h_aliases[i] != NULL; i++) 267 for (i=0; a->h_aliases[i] != NULL; i++)
266 ; 268 ;
267 i++; 269 i++;
268 ret->h_aliases=(char **)malloc(sizeof(char *)*i); 270 ret->h_aliases = (char **)Malloc(i*sizeof(char *));
269 memset(ret->h_aliases,0,sizeof(char *)*i); 271 if (ret->h_aliases == NULL)
270 if (ret == NULL) goto err; 272 goto err;
273 memset(ret->h_aliases, 0, i*sizeof(char *));
271 274
272 for (i=0; a->h_addr_list[i] != NULL; i++) 275 for (i=0; a->h_addr_list[i] != NULL; i++)
273 ; 276 ;
274 i++; 277 i++;
275 ret->h_addr_list=(char **)malloc(sizeof(char *)*i); 278 ret->h_addr_list=(char **)Malloc(i*sizeof(char *));
276 memset(ret->h_addr_list,0,sizeof(char *)*i); 279 if (ret->h_addr_list == NULL)
277 if (ret->h_addr_list == NULL) goto err; 280 goto err;
281 memset(ret->h_addr_list, 0, i*sizeof(char *));
278 282
279 j=strlen(a->h_name)+1; 283 j=strlen(a->h_name)+1;
280 if ((ret->h_name=malloc(j)) == NULL) goto err; 284 if ((ret->h_name=Malloc(j)) == NULL) goto err;
281 memcpy((char *)ret->h_name,a->h_name,j); 285 memcpy((char *)ret->h_name,a->h_name,j+1);
282 for (i=0; a->h_aliases[i] != NULL; i++) 286 for (i=0; a->h_aliases[i] != NULL; i++)
283 { 287 {
284 j=strlen(a->h_aliases[i])+1; 288 j=strlen(a->h_aliases[i])+1;
285 if ((ret->h_aliases[i]=malloc(j)) == NULL) goto err; 289 if ((ret->h_aliases[i]=Malloc(j)) == NULL) goto err;
286 memcpy(ret->h_aliases[i],a->h_aliases[i],j); 290 memcpy(ret->h_aliases[i],a->h_aliases[i],j+1);
287 } 291 }
288 ret->h_length=a->h_length; 292 ret->h_length=a->h_length;
289 ret->h_addrtype=a->h_addrtype; 293 ret->h_addrtype=a->h_addrtype;
290 for (i=0; a->h_addr_list[i] != NULL; i++) 294 for (i=0; a->h_addr_list[i] != NULL; i++)
291 { 295 {
292 if ((ret->h_addr_list[i]=malloc(a->h_length)) == NULL) 296 if ((ret->h_addr_list[i]=Malloc(a->h_length)) == NULL)
293 goto err; 297 goto err;
294 memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length); 298 memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length);
295 } 299 }
296 return(ret); 300 if (0)
301 {
297err: 302err:
298 if (ret != NULL) 303 if (ret != NULL)
299 ghbn_free(ret); 304 ghbn_free(ret);
300 return(NULL); 305 ret=NULL;
306 }
307 MemCheck_on();
308 return(ret);
301 } 309 }
302 310
303static void ghbn_free(a) 311static void ghbn_free(struct hostent *a)
304struct hostent *a;
305 { 312 {
306 int i; 313 int i;
307 314
315 if(a == NULL)
316 return;
317
308 if (a->h_aliases != NULL) 318 if (a->h_aliases != NULL)
309 { 319 {
310 for (i=0; a->h_aliases[i] != NULL; i++) 320 for (i=0; a->h_aliases[i] != NULL; i++)
311 free(a->h_aliases[i]); 321 Free(a->h_aliases[i]);
312 free(a->h_aliases); 322 Free(a->h_aliases);
313 } 323 }
314 if (a->h_addr_list != NULL) 324 if (a->h_addr_list != NULL)
315 { 325 {
316 for (i=0; a->h_addr_list[i] != NULL; i++) 326 for (i=0; a->h_addr_list[i] != NULL; i++)
317 free(a->h_addr_list[i]); 327 Free(a->h_addr_list[i]);
318 free(a->h_addr_list); 328 Free(a->h_addr_list);
319 } 329 }
320 if (a->h_name != NULL) free((char *)a->h_name); 330 if (a->h_name != NULL) Free((char *)a->h_name);
321 free(a); 331 Free(a);
322 } 332 }
323 333
324struct hostent *BIO_gethostbyname(name) 334struct hostent *BIO_gethostbyname(const char *name)
325char *name;
326 { 335 {
327 struct hostent *ret; 336 struct hostent *ret;
328 int i,lowi=0,j; 337 int i,lowi=0,j;
@@ -330,7 +339,12 @@ char *name;
330 339
331/* return(gethostbyname(name)); */ 340/* return(gethostbyname(name)); */
332 341
333 CRYPTO_w_lock(CRYPTO_LOCK_BIO_GETHOSTBYNAME); 342#if 0 /* It doesn't make sense to use locking here: The function interface
343 * is not thread-safe, because threads can never be sure when
344 * some other thread destroys the data they were given a pointer to.
345 */
346 CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
347#endif
334 j=strlen(name); 348 j=strlen(name);
335 if (j < 128) 349 if (j < 128)
336 { 350 {
@@ -356,15 +370,29 @@ char *name;
356 BIO_ghbn_miss++; 370 BIO_ghbn_miss++;
357 ret=gethostbyname(name); 371 ret=gethostbyname(name);
358 372
359 if (ret == NULL) return(NULL); 373 if (ret == NULL)
360 if (j > 128) return(ret); /* too big to cache */ 374 goto end;
375 if (j > 128) /* too big to cache */
376 {
377#if 0 /* If we were trying to make this function thread-safe (which
378 * is bound to fail), we'd have to give up in this case
379 * (or allocate more memory). */
380 ret = NULL;
381#endif
382 goto end;
383 }
361 384
362 /* else add to cache */ 385 /* else add to cache */
363 if (ghbn_cache[lowi].ent != NULL) 386 if (ghbn_cache[lowi].ent != NULL)
364 ghbn_free(ghbn_cache[lowi].ent); 387 ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
388 ghbn_cache[lowi].name[0] = '\0';
365 389
390 if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL)
391 {
392 BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE);
393 goto end;
394 }
366 strncpy(ghbn_cache[lowi].name,name,128); 395 strncpy(ghbn_cache[lowi].name,name,128);
367 ghbn_cache[lowi].ent=ghbn_dup(ret);
368 ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits; 396 ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits;
369 } 397 }
370 else 398 else
@@ -373,11 +401,14 @@ char *name;
373 ret= ghbn_cache[i].ent; 401 ret= ghbn_cache[i].ent;
374 ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits; 402 ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits;
375 } 403 }
376 CRYPTO_w_unlock(CRYPTO_LOCK_BIO_GETHOSTBYNAME); 404end:
405#if 0
406 CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
407#endif
377 return(ret); 408 return(ret);
378 } 409 }
379 410
380int BIO_sock_init() 411int BIO_sock_init(void)
381 { 412 {
382#ifdef WINDOWS 413#ifdef WINDOWS
383 static struct WSAData wsa_state; 414 static struct WSAData wsa_state;
@@ -403,7 +434,7 @@ int BIO_sock_init()
403 return(1); 434 return(1);
404 } 435 }
405 436
406void BIO_sock_cleanup() 437void BIO_sock_cleanup(void)
407 { 438 {
408#ifdef WINDOWS 439#ifdef WINDOWS
409 if (wsa_init_done) 440 if (wsa_init_done)
@@ -415,10 +446,9 @@ void BIO_sock_cleanup()
415#endif 446#endif
416 } 447 }
417 448
418int BIO_socket_ioctl(fd,type,arg) 449#if !defined(VMS) || __VMS_VER >= 70000000
419int fd; 450
420long type; 451int BIO_socket_ioctl(int fd, long type, unsigned long *arg)
421unsigned long *arg;
422 { 452 {
423 int i; 453 int i;
424 454
@@ -427,12 +457,11 @@ unsigned long *arg;
427 SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error()); 457 SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error());
428 return(i); 458 return(i);
429 } 459 }
460#endif /* __VMS_VER */
430 461
431/* The reason I have implemented this instead of using sscanf is because 462/* The reason I have implemented this instead of using sscanf is because
432 * Visual C 1.52c gives an unresolved external when linking a DLL :-( */ 463 * Visual C 1.52c gives an unresolved external when linking a DLL :-( */
433static int get_ip(str,ip) 464static int get_ip(const char *str, unsigned char ip[4])
434char *str;
435unsigned char ip[4];
436 { 465 {
437 unsigned int tmp[4]; 466 unsigned int tmp[4];
438 int num=0,c,ok=0; 467 int num=0,c,ok=0;
@@ -467,16 +496,17 @@ unsigned char ip[4];
467 return(1); 496 return(1);
468 } 497 }
469 498
470int BIO_get_accept_socket(host) 499int BIO_get_accept_socket(char *host, int bind_mode)
471char *host;
472 { 500 {
473 int ret=0; 501 int ret=0;
474 struct sockaddr_in server; 502 struct sockaddr_in server,client;
475 int s= -1; 503 int s= -1,cs;
476 unsigned char ip[4]; 504 unsigned char ip[4];
477 short port; 505 unsigned short port;
478 char *str,*h,*p,*e; 506 char *str,*e;
507 const char *h,*p;
479 unsigned long l; 508 unsigned long l;
509 int err_num;
480 510
481 if (!BIO_sock_init()) return(INVALID_SOCKET); 511 if (!BIO_sock_init()) return(INVALID_SOCKET);
482 512
@@ -508,7 +538,7 @@ char *host;
508 538
509 memset((char *)&server,0,sizeof(server)); 539 memset((char *)&server,0,sizeof(server));
510 server.sin_family=AF_INET; 540 server.sin_family=AF_INET;
511 server.sin_port=htons((unsigned short)port); 541 server.sin_port=htons(port);
512 542
513 if (strcmp(h,"*") == 0) 543 if (strcmp(h,"*") == 0)
514 server.sin_addr.s_addr=INADDR_ANY; 544 server.sin_addr.s_addr=INADDR_ANY;
@@ -517,12 +547,13 @@ char *host;
517 if (!BIO_get_host_ip(h,&(ip[0]))) return(INVALID_SOCKET); 547 if (!BIO_get_host_ip(h,&(ip[0]))) return(INVALID_SOCKET);
518 l=(unsigned long) 548 l=(unsigned long)
519 ((unsigned long)ip[0]<<24L)| 549 ((unsigned long)ip[0]<<24L)|
520 ((unsigned long)ip[0]<<16L)| 550 ((unsigned long)ip[1]<<16L)|
521 ((unsigned long)ip[0]<< 8L)| 551 ((unsigned long)ip[2]<< 8L)|
522 ((unsigned long)ip[0]); 552 ((unsigned long)ip[3]);
523 server.sin_addr.s_addr=htonl(l); 553 server.sin_addr.s_addr=htonl(l);
524 } 554 }
525 555
556again:
526 s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); 557 s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
527 if (s == INVALID_SOCKET) 558 if (s == INVALID_SOCKET)
528 { 559 {
@@ -531,9 +562,45 @@ char *host;
531 BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET); 562 BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET);
532 goto err; 563 goto err;
533 } 564 }
565
566#ifdef SO_REUSEADDR
567 if (bind_mode == BIO_BIND_REUSEADDR)
568 {
569 int i=1;
570
571 ret=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i));
572 bind_mode=BIO_BIND_NORMAL;
573 }
574#endif
534 if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1) 575 if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
535 { 576 {
536 SYSerr(SYS_F_BIND,get_last_socket_error()); 577#ifdef SO_REUSEADDR
578 err_num=get_last_socket_error();
579 if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
580 (err_num == EADDRINUSE))
581 {
582 memcpy((char *)&client,(char *)&server,sizeof(server));
583 if (strcmp(h,"*") == 0)
584 client.sin_addr.s_addr=htonl(0x7F000001);
585 cs=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
586 if (cs != INVALID_SOCKET)
587 {
588 int ii;
589 ii=connect(cs,(struct sockaddr *)&client,
590 sizeof(client));
591 closesocket(cs);
592 if (ii == INVALID_SOCKET)
593 {
594 bind_mode=BIO_BIND_REUSEADDR;
595 closesocket(s);
596 goto again;
597 }
598 /* else error */
599 }
600 /* else error */
601 }
602#endif
603 SYSerr(SYS_F_BIND,err_num);
537 ERR_add_error_data(3,"port='",host,"'"); 604 ERR_add_error_data(3,"port='",host,"'");
538 BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET); 605 BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET);
539 goto err; 606 goto err;
@@ -550,30 +617,29 @@ err:
550 if (str != NULL) Free(str); 617 if (str != NULL) Free(str);
551 if ((ret == 0) && (s != INVALID_SOCKET)) 618 if ((ret == 0) && (s != INVALID_SOCKET))
552 { 619 {
553#ifdef WINDOWS
554 closesocket(s); 620 closesocket(s);
555#else
556 close(s);
557#endif
558 s= INVALID_SOCKET; 621 s= INVALID_SOCKET;
559 } 622 }
560 return(s); 623 return(s);
561 } 624 }
562 625
563int BIO_accept(sock,addr) 626int BIO_accept(int sock, char **addr)
564int sock;
565char **addr;
566 { 627 {
567 int ret=INVALID_SOCKET; 628 int ret=INVALID_SOCKET;
568 static struct sockaddr_in from; 629 static struct sockaddr_in from;
569 unsigned long l; 630 unsigned long l;
570 short port; 631 unsigned short port;
571 int len; 632 int len;
572 char *p; 633 char *p;
573 634
574 memset((char *)&from,0,sizeof(from)); 635 memset((char *)&from,0,sizeof(from));
575 len=sizeof(from); 636 len=sizeof(from);
576 ret=accept(sock,(struct sockaddr *)&from,&len); 637 /* Note: under VMS with SOCKETSHR the fourth parameter is currently
638 * of type (int *) whereas under other systems it is (void *) if
639 * you don't have a cast it will choke the compiler: if you do
640 * have a cast then you can either go for (int *) or (void *).
641 */
642 ret=accept(sock,(struct sockaddr *)&from,(void *)&len);
577 if (ret == INVALID_SOCKET) 643 if (ret == INVALID_SOCKET)
578 { 644 {
579 SYSerr(SYS_F_ACCEPT,get_last_socket_error()); 645 SYSerr(SYS_F_ACCEPT,get_last_socket_error());
@@ -604,9 +670,7 @@ end:
604 return(ret); 670 return(ret);
605 } 671 }
606 672
607int BIO_set_tcp_ndelay(s,on) 673int BIO_set_tcp_ndelay(int s, int on)
608int s;
609int on;
610 { 674 {
611 int ret=0; 675 int ret=0;
612#if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP)) 676#if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
@@ -626,3 +690,14 @@ int on;
626 } 690 }
627#endif 691#endif
628 692
693int BIO_socket_nbio(int s, int mode)
694 {
695 int ret= -1;
696 unsigned long l;
697
698 l=mode;
699#ifdef FIONBIO
700 ret=BIO_socket_ioctl(s,FIONBIO,&l);
701#endif
702 return(ret == 0);
703 }