OLD | NEW |
1 /* crypto/bio/bio_dgram.c */ | 1 /* crypto/bio/bio_dgram.c */ |
2 /* | 2 /* |
3 * DTLS implementation written by Nagendra Modadugu | 3 * DTLS implementation written by Nagendra Modadugu |
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | 4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
5 */ | 5 */ |
6 /* ==================================================================== | 6 /* ==================================================================== |
7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. | 7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. |
8 * | 8 * |
9 * Redistribution and use in source and binary forms, with or without | 9 * Redistribution and use in source and binary forms, with or without |
10 * modification, are permitted provided that the following conditions | 10 * modification, are permitted provided that the following conditions |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
51 * OF THE POSSIBILITY OF SUCH DAMAGE. | 51 * OF THE POSSIBILITY OF SUCH DAMAGE. |
52 * ==================================================================== | 52 * ==================================================================== |
53 * | 53 * |
54 * This product includes cryptographic software written by Eric Young | 54 * This product includes cryptographic software written by Eric Young |
55 * (eay@cryptsoft.com). This product includes software written by Tim | 55 * (eay@cryptsoft.com). This product includes software written by Tim |
56 * Hudson (tjh@cryptsoft.com). | 56 * Hudson (tjh@cryptsoft.com). |
57 * | 57 * |
58 */ | 58 */ |
59 | 59 |
60 #ifndef OPENSSL_NO_DGRAM | |
61 | 60 |
62 #include <stdio.h> | 61 #include <stdio.h> |
63 #include <errno.h> | 62 #include <errno.h> |
64 #define USE_SOCKETS | 63 #define USE_SOCKETS |
65 #include "cryptlib.h" | 64 #include "cryptlib.h" |
66 | 65 |
67 #include <openssl/bio.h> | 66 #include <openssl/bio.h> |
| 67 #ifndef OPENSSL_NO_DGRAM |
68 | 68 |
69 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) | 69 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) |
70 #include <sys/timeb.h> | 70 #include <sys/timeb.h> |
71 #endif | 71 #endif |
72 | 72 |
73 #ifdef OPENSSL_SYS_LINUX | 73 #ifdef OPENSSL_SYS_LINUX |
74 #define IP_MTU 14 /* linux is lame */ | 74 #define IP_MTU 14 /* linux is lame */ |
75 #endif | 75 #endif |
76 | 76 |
77 #ifdef WATT32 | 77 #ifdef WATT32 |
(...skipping 23 matching lines...) Expand all Loading... |
101 dgram_puts, | 101 dgram_puts, |
102 NULL, /* dgram_gets, */ | 102 NULL, /* dgram_gets, */ |
103 dgram_ctrl, | 103 dgram_ctrl, |
104 dgram_new, | 104 dgram_new, |
105 dgram_free, | 105 dgram_free, |
106 NULL, | 106 NULL, |
107 }; | 107 }; |
108 | 108 |
109 typedef struct bio_dgram_data_st | 109 typedef struct bio_dgram_data_st |
110 { | 110 { |
111 » struct sockaddr peer; | 111 » union { |
| 112 » » struct sockaddr sa; |
| 113 » » struct sockaddr_in sa_in; |
| 114 #if OPENSSL_USE_IPV6 |
| 115 » » struct sockaddr_in6 sa_in6; |
| 116 #endif |
| 117 » } peer; |
112 unsigned int connected; | 118 unsigned int connected; |
113 unsigned int _errno; | 119 unsigned int _errno; |
114 unsigned int mtu; | 120 unsigned int mtu; |
115 struct timeval next_timeout; | 121 struct timeval next_timeout; |
116 struct timeval socket_timeout; | 122 struct timeval socket_timeout; |
117 } bio_dgram_data; | 123 } bio_dgram_data; |
118 | 124 |
119 BIO_METHOD *BIO_s_datagram(void) | 125 BIO_METHOD *BIO_s_datagram(void) |
120 { | 126 { |
121 return(&methods_dgramp); | 127 return(&methods_dgramp); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 #endif | 273 #endif |
268 } | 274 } |
269 #endif | 275 #endif |
270 } | 276 } |
271 | 277 |
272 static int dgram_read(BIO *b, char *out, int outl) | 278 static int dgram_read(BIO *b, char *out, int outl) |
273 { | 279 { |
274 int ret=0; | 280 int ret=0; |
275 bio_dgram_data *data = (bio_dgram_data *)b->ptr; | 281 bio_dgram_data *data = (bio_dgram_data *)b->ptr; |
276 | 282 |
277 » struct sockaddr peer; | 283 » struct» { |
278 » int peerlen = sizeof(peer); | 284 » /* |
| 285 » * See commentary in b_sock.c. <appro> |
| 286 » */ |
| 287 » union» { size_t s; int i; } len; |
| 288 » union» { |
| 289 » » struct sockaddr sa; |
| 290 » » struct sockaddr_in sa_in; |
| 291 #if OPENSSL_USE_IPV6 |
| 292 » » struct sockaddr_in6 sa_in6; |
| 293 #endif |
| 294 » » } peer; |
| 295 » } sa; |
| 296 |
| 297 » sa.len.s=0; |
| 298 » sa.len.i=sizeof(sa.peer); |
279 | 299 |
280 if (out != NULL) | 300 if (out != NULL) |
281 { | 301 { |
282 clear_socket_error(); | 302 clear_socket_error(); |
283 » » memset(&peer, 0x00, peerlen); | 303 » » memset(&sa.peer, 0x00, sizeof(sa.peer)); |
284 » » /* Last arg in recvfrom is signed on some platforms and | |
285 » » * unsigned on others. It is of type socklen_t on some | |
286 » » * but this is not universal. Cast to (void *) to avoid | |
287 » » * compiler warnings. | |
288 » » */ | |
289 dgram_adjust_rcv_timeout(b); | 304 dgram_adjust_rcv_timeout(b); |
290 » » ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); | 305 » » ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len); |
291 » » dgram_reset_rcv_timeout(b); | 306 » » if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0) |
| 307 » » » { |
| 308 » » » OPENSSL_assert(sa.len.s<=sizeof(sa.peer)); |
| 309 » » » sa.len.i = (int)sa.len.s; |
| 310 » » » } |
292 | 311 |
293 if ( ! data->connected && ret >= 0) | 312 if ( ! data->connected && ret >= 0) |
294 » » » BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer); | 313 » » » BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); |
295 | 314 |
296 BIO_clear_retry_flags(b); | 315 BIO_clear_retry_flags(b); |
297 if (ret < 0) | 316 if (ret < 0) |
298 { | 317 { |
299 if (BIO_dgram_should_retry(ret)) | 318 if (BIO_dgram_should_retry(ret)) |
300 { | 319 { |
301 BIO_set_retry_read(b); | 320 BIO_set_retry_read(b); |
302 data->_errno = get_last_socket_error(); | 321 data->_errno = get_last_socket_error(); |
303 } | 322 } |
304 } | 323 } |
| 324 |
| 325 dgram_reset_rcv_timeout(b); |
305 } | 326 } |
306 return(ret); | 327 return(ret); |
307 } | 328 } |
308 | 329 |
309 static int dgram_write(BIO *b, const char *in, int inl) | 330 static int dgram_write(BIO *b, const char *in, int inl) |
310 { | 331 { |
311 int ret; | 332 int ret; |
312 bio_dgram_data *data = (bio_dgram_data *)b->ptr; | 333 bio_dgram_data *data = (bio_dgram_data *)b->ptr; |
313 clear_socket_error(); | 334 clear_socket_error(); |
314 | 335 |
315 if ( data->connected ) | 336 » if ( data->connected ) |
316 ret=writesocket(b->num,in,inl); | 337 » » ret=writesocket(b->num,in,inl); |
317 else | 338 » else |
| 339 » » { |
| 340 » » int peerlen = sizeof(data->peer); |
| 341 |
| 342 » » if (data->peer.sa.sa_family == AF_INET) |
| 343 » » » peerlen = sizeof(data->peer.sa_in); |
| 344 #if OPENSSL_USE_IPV6 |
| 345 » » else if (data->peer.sa.sa_family == AF_INET6) |
| 346 » » » peerlen = sizeof(data->peer.sa_in6); |
| 347 #endif |
318 #if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) | 348 #if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) |
319 ret=sendto(b->num, (char *)in, inl, 0, &data->peer, sizeof(data->peer)); | 349 » » ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen); |
320 #else | 350 #else |
321 ret=sendto(b->num, in, inl, 0, &data->peer, sizeof(data->peer)); | 351 » » ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); |
322 #endif | 352 #endif |
| 353 } |
323 | 354 |
324 BIO_clear_retry_flags(b); | 355 BIO_clear_retry_flags(b); |
325 if (ret <= 0) | 356 if (ret <= 0) |
326 { | 357 { |
327 if (BIO_dgram_should_retry(ret)) | 358 if (BIO_dgram_should_retry(ret)) |
328 { | 359 { |
329 BIO_set_retry_write(b); | 360 BIO_set_retry_write(b); |
330 data->_errno = get_last_socket_error(); | 361 data->_errno = get_last_socket_error(); |
331 | 362 |
332 #if 0 /* higher layers are responsible for querying MTU, if necessary */ | 363 #if 0 /* higher layers are responsible for querying MTU, if necessary */ |
(...skipping 11 matching lines...) Expand all Loading... |
344 long ret=1; | 375 long ret=1; |
345 int *ip; | 376 int *ip; |
346 struct sockaddr *to = NULL; | 377 struct sockaddr *to = NULL; |
347 bio_dgram_data *data = NULL; | 378 bio_dgram_data *data = NULL; |
348 #if defined(IP_MTU_DISCOVER) || defined(IP_MTU) | 379 #if defined(IP_MTU_DISCOVER) || defined(IP_MTU) |
349 long sockopt_val = 0; | 380 long sockopt_val = 0; |
350 unsigned int sockopt_len = 0; | 381 unsigned int sockopt_len = 0; |
351 #endif | 382 #endif |
352 #ifdef OPENSSL_SYS_LINUX | 383 #ifdef OPENSSL_SYS_LINUX |
353 socklen_t addr_len; | 384 socklen_t addr_len; |
354 » struct sockaddr_storage addr; | 385 » union» { |
| 386 » » struct sockaddr»sa; |
| 387 » » struct sockaddr_in s4; |
| 388 #if OPENSSL_USE_IPV6 |
| 389 » » struct sockaddr_in6 s6; |
| 390 #endif |
| 391 » » } addr; |
355 #endif | 392 #endif |
356 | 393 |
357 data = (bio_dgram_data *)b->ptr; | 394 data = (bio_dgram_data *)b->ptr; |
358 | 395 |
359 switch (cmd) | 396 switch (cmd) |
360 { | 397 { |
361 case BIO_CTRL_RESET: | 398 case BIO_CTRL_RESET: |
362 num=0; | 399 num=0; |
363 case BIO_C_FILE_SEEK: | 400 case BIO_C_FILE_SEEK: |
364 ret=0; | 401 ret=0; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 ret=1; | 435 ret=1; |
399 break; | 436 break; |
400 case BIO_CTRL_DGRAM_CONNECT: | 437 case BIO_CTRL_DGRAM_CONNECT: |
401 to = (struct sockaddr *)ptr; | 438 to = (struct sockaddr *)ptr; |
402 #if 0 | 439 #if 0 |
403 if (connect(b->num, to, sizeof(struct sockaddr)) < 0) | 440 if (connect(b->num, to, sizeof(struct sockaddr)) < 0) |
404 { perror("connect"); ret = 0; } | 441 { perror("connect"); ret = 0; } |
405 else | 442 else |
406 { | 443 { |
407 #endif | 444 #endif |
408 » » » memcpy(&(data->peer),to, sizeof(struct sockaddr)); | 445 » » » switch (to->sa_family) |
| 446 » » » » { |
| 447 » » » » case AF_INET: |
| 448 » » » » » memcpy(&data->peer,to,sizeof(data->peer.
sa_in)); |
| 449 » » » » » break; |
| 450 #if OPENSSL_USE_IPV6 |
| 451 » » » » case AF_INET6: |
| 452 » » » » » memcpy(&data->peer,to,sizeof(data->peer.
sa_in6)); |
| 453 » » » » » break; |
| 454 #endif |
| 455 » » » » default: |
| 456 » » » » » memcpy(&data->peer,to,sizeof(data->peer.
sa)); |
| 457 » » » » » break; |
| 458 » » » » } |
409 #if 0 | 459 #if 0 |
410 } | 460 } |
411 #endif | 461 #endif |
412 break; | 462 break; |
413 /* (Linux)kernel sets DF bit on outgoing IP packets */ | 463 /* (Linux)kernel sets DF bit on outgoing IP packets */ |
414 case BIO_CTRL_DGRAM_MTU_DISCOVER: | 464 case BIO_CTRL_DGRAM_MTU_DISCOVER: |
415 #ifdef OPENSSL_SYS_LINUX | 465 #ifdef OPENSSL_SYS_LINUX |
416 » » addr_len = (socklen_t)sizeof(struct sockaddr_storage); | 466 » » addr_len = (socklen_t)sizeof(addr); |
417 » » memset((void *)&addr, 0, sizeof(struct sockaddr_storage)); | 467 » » memset((void *)&addr, 0, sizeof(addr)); |
418 » » if (getsockname(b->num, (void *)&addr, &addr_len) < 0) | 468 » » if (getsockname(b->num, &addr.sa, &addr_len) < 0) |
419 { | 469 { |
420 ret = 0; | 470 ret = 0; |
421 break; | 471 break; |
422 } | 472 } |
423 sockopt_len = sizeof(sockopt_val); | 473 sockopt_len = sizeof(sockopt_val); |
424 » » switch (addr.ss_family) | 474 » » switch (addr.sa.sa_family) |
425 { | 475 { |
426 case AF_INET: | 476 case AF_INET: |
427 sockopt_val = IP_PMTUDISC_DO; | 477 sockopt_val = IP_PMTUDISC_DO; |
428 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVE
R, | 478 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVE
R, |
429 &sockopt_val, sizeof(sockopt_val))) < 0) | 479 &sockopt_val, sizeof(sockopt_val))) < 0) |
430 perror("setsockopt"); | 480 perror("setsockopt"); |
431 break; | 481 break; |
| 482 #if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) |
432 case AF_INET6: | 483 case AF_INET6: |
433 sockopt_val = IPV6_PMTUDISC_DO; | 484 sockopt_val = IPV6_PMTUDISC_DO; |
434 if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DIS
COVER, | 485 if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DIS
COVER, |
435 &sockopt_val, sizeof(sockopt_val))) < 0) | 486 &sockopt_val, sizeof(sockopt_val))) < 0) |
436 perror("setsockopt"); | 487 perror("setsockopt"); |
437 break; | 488 break; |
| 489 #endif |
438 default: | 490 default: |
439 ret = -1; | 491 ret = -1; |
440 break; | 492 break; |
441 } | 493 } |
442 ret = -1; | 494 ret = -1; |
443 #else | 495 #else |
444 break; | 496 break; |
445 #endif | 497 #endif |
446 case BIO_CTRL_DGRAM_QUERY_MTU: | 498 case BIO_CTRL_DGRAM_QUERY_MTU: |
447 #ifdef OPENSSL_SYS_LINUX | 499 #ifdef OPENSSL_SYS_LINUX |
448 » » addr_len = (socklen_t)sizeof(struct sockaddr_storage); | 500 » » addr_len = (socklen_t)sizeof(addr); |
449 » » memset((void *)&addr, 0, sizeof(struct sockaddr_storage)); | 501 » » memset((void *)&addr, 0, sizeof(addr)); |
450 » » if (getsockname(b->num, (void *)&addr, &addr_len) < 0) | 502 » » if (getsockname(b->num, &addr.sa, &addr_len) < 0) |
451 { | 503 { |
452 ret = 0; | 504 ret = 0; |
453 break; | 505 break; |
454 } | 506 } |
455 sockopt_len = sizeof(sockopt_val); | 507 sockopt_len = sizeof(sockopt_val); |
456 » » switch (addr.ss_family) | 508 » » switch (addr.sa.sa_family) |
457 { | 509 { |
458 case AF_INET: | 510 case AF_INET: |
459 if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void
*)&sockopt_val, | 511 if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void
*)&sockopt_val, |
460 &sockopt_len)) < 0 || sockopt_val < 0) | 512 &sockopt_len)) < 0 || sockopt_val < 0) |
461 { | 513 { |
462 ret = 0; | 514 ret = 0; |
463 } | 515 } |
464 else | 516 else |
465 { | 517 { |
466 /* we assume that the transport protocol is UDP
and no | 518 /* we assume that the transport protocol is UDP
and no |
467 * IP options are used. | 519 * IP options are used. |
468 */ | 520 */ |
469 data->mtu = sockopt_val - 8 - 20; | 521 data->mtu = sockopt_val - 8 - 20; |
470 ret = data->mtu; | 522 ret = data->mtu; |
471 } | 523 } |
472 break; | 524 break; |
| 525 #if OPENSSL_USE_IPV6 && defined(IPV6_MTU) |
473 case AF_INET6: | 526 case AF_INET6: |
474 if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (v
oid *)&sockopt_val, | 527 if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (v
oid *)&sockopt_val, |
475 &sockopt_len)) < 0 || sockopt_val < 0) | 528 &sockopt_len)) < 0 || sockopt_val < 0) |
476 { | 529 { |
477 ret = 0; | 530 ret = 0; |
478 } | 531 } |
479 else | 532 else |
480 { | 533 { |
481 /* we assume that the transport protocol is UDP
and no | 534 /* we assume that the transport protocol is UDP
and no |
482 * IPV6 options are used. | 535 * IPV6 options are used. |
483 */ | 536 */ |
484 data->mtu = sockopt_val - 8 - 40; | 537 data->mtu = sockopt_val - 8 - 40; |
485 ret = data->mtu; | 538 ret = data->mtu; |
486 } | 539 } |
487 break; | 540 break; |
| 541 #endif |
488 default: | 542 default: |
489 ret = 0; | 543 ret = 0; |
490 break; | 544 break; |
491 } | 545 } |
492 #else | 546 #else |
493 ret = 0; | 547 ret = 0; |
494 #endif | 548 #endif |
495 break; | 549 break; |
496 case BIO_CTRL_DGRAM_GET_MTU: | 550 case BIO_CTRL_DGRAM_GET_MTU: |
497 return data->mtu; | 551 return data->mtu; |
498 break; | 552 break; |
499 case BIO_CTRL_DGRAM_SET_MTU: | 553 case BIO_CTRL_DGRAM_SET_MTU: |
500 data->mtu = num; | 554 data->mtu = num; |
501 ret = num; | 555 ret = num; |
502 break; | 556 break; |
503 case BIO_CTRL_DGRAM_SET_CONNECTED: | 557 case BIO_CTRL_DGRAM_SET_CONNECTED: |
504 to = (struct sockaddr *)ptr; | 558 to = (struct sockaddr *)ptr; |
505 | 559 |
506 if ( to != NULL) | 560 if ( to != NULL) |
507 { | 561 { |
508 data->connected = 1; | 562 data->connected = 1; |
509 » » » memcpy(&(data->peer),to, sizeof(struct sockaddr)); | 563 » » » switch (to->sa_family) |
| 564 » » » » { |
| 565 » » » » case AF_INET: |
| 566 » » » » » memcpy(&data->peer,to,sizeof(data->peer.
sa_in)); |
| 567 » » » » » break; |
| 568 #if OPENSSL_USE_IPV6 |
| 569 » » » » case AF_INET6: |
| 570 » » » » » memcpy(&data->peer,to,sizeof(data->peer.
sa_in6)); |
| 571 » » » » » break; |
| 572 #endif |
| 573 » » » » default: |
| 574 » » » » » memcpy(&data->peer,to,sizeof(data->peer.
sa)); |
| 575 » » » » » break; |
| 576 » » » » } |
510 } | 577 } |
511 else | 578 else |
512 { | 579 { |
513 data->connected = 0; | 580 data->connected = 0; |
514 » » » memset(&(data->peer), 0x00, sizeof(struct sockaddr)); | 581 » » » memset(&(data->peer), 0x00, sizeof(data->peer)); |
515 } | 582 } |
516 break; | 583 break; |
517 case BIO_CTRL_DGRAM_GET_PEER: | 584 » case BIO_CTRL_DGRAM_GET_PEER: |
518 to = (struct sockaddr *) ptr; | 585 » » switch (data->peer.sa.sa_family) |
519 | 586 » » » { |
520 memcpy(to, &(data->peer), sizeof(struct sockaddr)); | 587 » » » case AF_INET: |
521 » » ret = sizeof(struct sockaddr); | 588 » » » » ret=sizeof(data->peer.sa_in); |
522 break; | 589 » » » » break; |
523 case BIO_CTRL_DGRAM_SET_PEER: | 590 #if OPENSSL_USE_IPV6 |
524 to = (struct sockaddr *) ptr; | 591 » » » case AF_INET6: |
525 | 592 » » » » ret=sizeof(data->peer.sa_in6); |
526 memcpy(&(data->peer), to, sizeof(struct sockaddr)); | 593 » » » » break; |
527 break; | 594 #endif |
| 595 » » » default: |
| 596 » » » » ret=sizeof(data->peer.sa); |
| 597 » » » » break; |
| 598 » » » } |
| 599 » » if (num==0 || num>ret) |
| 600 » » » num=ret; |
| 601 » » memcpy(ptr,&data->peer,(ret=num)); |
| 602 » » break; |
| 603 » case BIO_CTRL_DGRAM_SET_PEER: |
| 604 » » to = (struct sockaddr *) ptr; |
| 605 » » switch (to->sa_family) |
| 606 » » » { |
| 607 » » » case AF_INET: |
| 608 » » » » memcpy(&data->peer,to,sizeof(data->peer.sa_in)); |
| 609 » » » » break; |
| 610 #if OPENSSL_USE_IPV6 |
| 611 » » » case AF_INET6: |
| 612 » » » » memcpy(&data->peer,to,sizeof(data->peer.sa_in6))
; |
| 613 » » » » break; |
| 614 #endif |
| 615 » » » default: |
| 616 » » » » memcpy(&data->peer,to,sizeof(data->peer.sa)); |
| 617 » » » » break; |
| 618 » » » } |
| 619 » » break; |
528 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: | 620 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: |
529 » » memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));»
» | 621 » » memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); |
530 break; | 622 break; |
531 #if defined(SO_RCVTIMEO) | 623 #if defined(SO_RCVTIMEO) |
532 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: | 624 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: |
533 #ifdef OPENSSL_SYS_WINDOWS | 625 #ifdef OPENSSL_SYS_WINDOWS |
534 { | 626 { |
535 struct timeval *tv = (struct timeval *)ptr; | 627 struct timeval *tv = (struct timeval *)ptr; |
536 int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; | 628 int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; |
537 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, | 629 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, |
538 (void*)&timeout, sizeof(timeout)) < 0) | 630 (void*)&timeout, sizeof(timeout)) < 0) |
539 { perror("setsockopt"); ret = -1; } | 631 { perror("setsockopt"); ret = -1; } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 } | 739 } |
648 | 740 |
649 static int BIO_dgram_should_retry(int i) | 741 static int BIO_dgram_should_retry(int i) |
650 { | 742 { |
651 int err; | 743 int err; |
652 | 744 |
653 if ((i == 0) || (i == -1)) | 745 if ((i == 0) || (i == -1)) |
654 { | 746 { |
655 err=get_last_socket_error(); | 747 err=get_last_socket_error(); |
656 | 748 |
657 #if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not?
Ben 4/1/99 */ | 749 #if defined(OPENSSL_SYS_WINDOWS) |
658 » » if ((i == -1) && (err == 0)) | 750 » /* If the socket return value (i) is -1 |
659 » » » return(1); | 751 » * and err is unexpectedly 0 at this point, |
| 752 » * the error code was overwritten by |
| 753 » * another system call before this error |
| 754 » * handling is called. |
| 755 » */ |
660 #endif | 756 #endif |
661 | 757 |
662 return(BIO_dgram_non_fatal_error(err)); | 758 return(BIO_dgram_non_fatal_error(err)); |
663 } | 759 } |
664 return(0); | 760 return(0); |
665 } | 761 } |
666 | 762 |
667 int BIO_dgram_non_fatal_error(int err) | 763 int BIO_dgram_non_fatal_error(int err) |
668 { | 764 { |
669 switch (err) | 765 switch (err) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 case EALREADY: | 808 case EALREADY: |
713 #endif | 809 #endif |
714 | 810 |
715 return(1); | 811 return(1); |
716 /* break; */ | 812 /* break; */ |
717 default: | 813 default: |
718 break; | 814 break; |
719 } | 815 } |
720 return(0); | 816 return(0); |
721 } | 817 } |
722 #endif | |
723 | 818 |
724 static void get_current_time(struct timeval *t) | 819 static void get_current_time(struct timeval *t) |
725 { | 820 { |
726 #ifdef OPENSSL_SYS_WIN32 | 821 #ifdef OPENSSL_SYS_WIN32 |
727 struct _timeb tb; | 822 struct _timeb tb; |
728 _ftime(&tb); | 823 _ftime(&tb); |
729 t->tv_sec = (long)tb.time; | 824 t->tv_sec = (long)tb.time; |
730 t->tv_usec = (long)tb.millitm * 1000; | 825 t->tv_usec = (long)tb.millitm * 1000; |
731 #elif defined(OPENSSL_SYS_VMS) | 826 #elif defined(OPENSSL_SYS_VMS) |
732 struct timeb tb; | 827 struct timeb tb; |
733 ftime(&tb); | 828 ftime(&tb); |
734 t->tv_sec = (long)tb.time; | 829 t->tv_sec = (long)tb.time; |
735 t->tv_usec = (long)tb.millitm * 1000; | 830 t->tv_usec = (long)tb.millitm * 1000; |
736 #else | 831 #else |
737 gettimeofday(t, NULL); | 832 gettimeofday(t, NULL); |
738 #endif | 833 #endif |
739 } | 834 } |
| 835 |
| 836 #endif |
OLD | NEW |