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