| 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 |