bss_dgram.c revision 279264
1/* crypto/bio/bio_dgram.c */ 2/* 3 * DTLS implementation written by Nagendra Modadugu 4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. 5 */ 6/* ==================================================================== 7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * openssl-core@OpenSSL.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 * 54 * This product includes cryptographic software written by Eric Young 55 * (eay@cryptsoft.com). This product includes software written by Tim 56 * Hudson (tjh@cryptsoft.com). 57 * 58 */ 59 60 61#include <stdio.h> 62#include <errno.h> 63#define USE_SOCKETS 64#include "cryptlib.h" 65 66#include <openssl/bio.h> 67#ifndef OPENSSL_NO_DGRAM 68 69#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) 70#include <sys/timeb.h> 71#endif 72 73#ifndef OPENSSL_NO_SCTP 74#include <netinet/sctp.h> 75#include <fcntl.h> 76#define OPENSSL_SCTP_DATA_CHUNK_TYPE 0x00 77#define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0 78#endif 79 80#if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU) 81#define IP_MTU 14 /* linux is lame */ 82#endif 83 84#if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED) 85/* Standard definition causes type-punning problems. */ 86#undef IN6_IS_ADDR_V4MAPPED 87#define s6_addr32 __u6_addr.__u6_addr32 88#define IN6_IS_ADDR_V4MAPPED(a) \ 89 (((a)->s6_addr32[0] == 0) && \ 90 ((a)->s6_addr32[1] == 0) && \ 91 ((a)->s6_addr32[2] == htonl(0x0000ffff))) 92#endif 93 94#ifdef WATT32 95#define sock_write SockWrite /* Watt-32 uses same names */ 96#define sock_read SockRead 97#define sock_puts SockPuts 98#endif 99 100static int dgram_write(BIO *h, const char *buf, int num); 101static int dgram_read(BIO *h, char *buf, int size); 102static int dgram_puts(BIO *h, const char *str); 103static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2); 104static int dgram_new(BIO *h); 105static int dgram_free(BIO *data); 106static int dgram_clear(BIO *bio); 107 108#ifndef OPENSSL_NO_SCTP 109static int dgram_sctp_write(BIO *h, const char *buf, int num); 110static int dgram_sctp_read(BIO *h, char *buf, int size); 111static int dgram_sctp_puts(BIO *h, const char *str); 112static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2); 113static int dgram_sctp_new(BIO *h); 114static int dgram_sctp_free(BIO *data); 115#ifdef SCTP_AUTHENTICATION_EVENT 116static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp); 117#endif 118#endif 119 120static int BIO_dgram_should_retry(int s); 121 122static void get_current_time(struct timeval *t); 123 124static BIO_METHOD methods_dgramp= 125 { 126 BIO_TYPE_DGRAM, 127 "datagram socket", 128 dgram_write, 129 dgram_read, 130 dgram_puts, 131 NULL, /* dgram_gets, */ 132 dgram_ctrl, 133 dgram_new, 134 dgram_free, 135 NULL, 136 }; 137 138#ifndef OPENSSL_NO_SCTP 139static BIO_METHOD methods_dgramp_sctp= 140 { 141 BIO_TYPE_DGRAM_SCTP, 142 "datagram sctp socket", 143 dgram_sctp_write, 144 dgram_sctp_read, 145 dgram_sctp_puts, 146 NULL, /* dgram_gets, */ 147 dgram_sctp_ctrl, 148 dgram_sctp_new, 149 dgram_sctp_free, 150 NULL, 151 }; 152#endif 153 154typedef struct bio_dgram_data_st 155 { 156 union { 157 struct sockaddr sa; 158 struct sockaddr_in sa_in; 159#if OPENSSL_USE_IPV6 160 struct sockaddr_in6 sa_in6; 161#endif 162 } peer; 163 unsigned int connected; 164 unsigned int _errno; 165 unsigned int mtu; 166 struct timeval next_timeout; 167 struct timeval socket_timeout; 168 } bio_dgram_data; 169 170#ifndef OPENSSL_NO_SCTP 171typedef struct bio_dgram_sctp_save_message_st 172 { 173 BIO *bio; 174 char *data; 175 int length; 176 } bio_dgram_sctp_save_message; 177 178typedef struct bio_dgram_sctp_data_st 179 { 180 union { 181 struct sockaddr sa; 182 struct sockaddr_in sa_in; 183#if OPENSSL_USE_IPV6 184 struct sockaddr_in6 sa_in6; 185#endif 186 } peer; 187 unsigned int connected; 188 unsigned int _errno; 189 unsigned int mtu; 190 struct bio_dgram_sctp_sndinfo sndinfo; 191 struct bio_dgram_sctp_rcvinfo rcvinfo; 192 struct bio_dgram_sctp_prinfo prinfo; 193 void (*handle_notifications)(BIO *bio, void *context, void *buf); 194 void* notification_context; 195 int in_handshake; 196 int ccs_rcvd; 197 int ccs_sent; 198 int save_shutdown; 199 int peer_auth_tested; 200 bio_dgram_sctp_save_message saved_message; 201 } bio_dgram_sctp_data; 202#endif 203 204BIO_METHOD *BIO_s_datagram(void) 205 { 206 return(&methods_dgramp); 207 } 208 209BIO *BIO_new_dgram(int fd, int close_flag) 210 { 211 BIO *ret; 212 213 ret=BIO_new(BIO_s_datagram()); 214 if (ret == NULL) return(NULL); 215 BIO_set_fd(ret,fd,close_flag); 216 return(ret); 217 } 218 219static int dgram_new(BIO *bi) 220 { 221 bio_dgram_data *data = NULL; 222 223 bi->init=0; 224 bi->num=0; 225 data = OPENSSL_malloc(sizeof(bio_dgram_data)); 226 if (data == NULL) 227 return 0; 228 memset(data, 0x00, sizeof(bio_dgram_data)); 229 bi->ptr = data; 230 231 bi->flags=0; 232 return(1); 233 } 234 235static int dgram_free(BIO *a) 236 { 237 bio_dgram_data *data; 238 239 if (a == NULL) return(0); 240 if ( ! dgram_clear(a)) 241 return 0; 242 243 data = (bio_dgram_data *)a->ptr; 244 if(data != NULL) OPENSSL_free(data); 245 246 return(1); 247 } 248 249static int dgram_clear(BIO *a) 250 { 251 if (a == NULL) return(0); 252 if (a->shutdown) 253 { 254 if (a->init) 255 { 256 SHUTDOWN2(a->num); 257 } 258 a->init=0; 259 a->flags=0; 260 } 261 return(1); 262 } 263 264static void dgram_adjust_rcv_timeout(BIO *b) 265 { 266#if defined(SO_RCVTIMEO) 267 bio_dgram_data *data = (bio_dgram_data *)b->ptr; 268 union { size_t s; int i; } sz = {0}; 269 270 /* Is a timer active? */ 271 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) 272 { 273 struct timeval timenow, timeleft; 274 275 /* Read current socket timeout */ 276#ifdef OPENSSL_SYS_WINDOWS 277 int timeout; 278 279 sz.i = sizeof(timeout); 280 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 281 (void*)&timeout, &sz.i) < 0) 282 { perror("getsockopt"); } 283 else 284 { 285 data->socket_timeout.tv_sec = timeout / 1000; 286 data->socket_timeout.tv_usec = (timeout % 1000) * 1000; 287 } 288#else 289 sz.i = sizeof(data->socket_timeout); 290 if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 291 &(data->socket_timeout), (void *)&sz) < 0) 292 { perror("getsockopt"); } 293 else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) 294 OPENSSL_assert(sz.s<=sizeof(data->socket_timeout)); 295#endif 296 297 /* Get current time */ 298 get_current_time(&timenow); 299 300 /* Calculate time left until timer expires */ 301 memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); 302 timeleft.tv_sec -= timenow.tv_sec; 303 timeleft.tv_usec -= timenow.tv_usec; 304 if (timeleft.tv_usec < 0) 305 { 306 timeleft.tv_sec--; 307 timeleft.tv_usec += 1000000; 308 } 309 310 if (timeleft.tv_sec < 0) 311 { 312 timeleft.tv_sec = 0; 313 timeleft.tv_usec = 1; 314 } 315 316 /* Adjust socket timeout if next handhake message timer 317 * will expire earlier. 318 */ 319 if ((data->socket_timeout.tv_sec == 0 && data->socket_timeout.tv_usec == 0) || 320 (data->socket_timeout.tv_sec > timeleft.tv_sec) || 321 (data->socket_timeout.tv_sec == timeleft.tv_sec && 322 data->socket_timeout.tv_usec >= timeleft.tv_usec)) 323 { 324#ifdef OPENSSL_SYS_WINDOWS 325 timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; 326 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 327 (void*)&timeout, sizeof(timeout)) < 0) 328 { perror("setsockopt"); } 329#else 330 if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, 331 sizeof(struct timeval)) < 0) 332 { perror("setsockopt"); } 333#endif 334 } 335 } 336#endif 337 } 338 339static void dgram_reset_rcv_timeout(BIO *b) 340 { 341#if defined(SO_RCVTIMEO) 342 bio_dgram_data *data = (bio_dgram_data *)b->ptr; 343 344 /* Is a timer active? */ 345 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) 346 { 347#ifdef OPENSSL_SYS_WINDOWS 348 int timeout = data->socket_timeout.tv_sec * 1000 + 349 data->socket_timeout.tv_usec / 1000; 350 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 351 (void*)&timeout, sizeof(timeout)) < 0) 352 { perror("setsockopt"); } 353#else 354 if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), 355 sizeof(struct timeval)) < 0) 356 { perror("setsockopt"); } 357#endif 358 } 359#endif 360 } 361 362static int dgram_read(BIO *b, char *out, int outl) 363 { 364 int ret=0; 365 bio_dgram_data *data = (bio_dgram_data *)b->ptr; 366 367 struct { 368 /* 369 * See commentary in b_sock.c. <appro> 370 */ 371 union { size_t s; int i; } len; 372 union { 373 struct sockaddr sa; 374 struct sockaddr_in sa_in; 375#if OPENSSL_USE_IPV6 376 struct sockaddr_in6 sa_in6; 377#endif 378 } peer; 379 } sa; 380 381 sa.len.s=0; 382 sa.len.i=sizeof(sa.peer); 383 384 if (out != NULL) 385 { 386 clear_socket_error(); 387 memset(&sa.peer, 0x00, sizeof(sa.peer)); 388 dgram_adjust_rcv_timeout(b); 389 ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len); 390 if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0) 391 { 392 OPENSSL_assert(sa.len.s<=sizeof(sa.peer)); 393 sa.len.i = (int)sa.len.s; 394 } 395 396 if ( ! data->connected && ret >= 0) 397 BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); 398 399 BIO_clear_retry_flags(b); 400 if (ret < 0) 401 { 402 if (BIO_dgram_should_retry(ret)) 403 { 404 BIO_set_retry_read(b); 405 data->_errno = get_last_socket_error(); 406 } 407 } 408 409 dgram_reset_rcv_timeout(b); 410 } 411 return(ret); 412 } 413 414static int dgram_write(BIO *b, const char *in, int inl) 415 { 416 int ret; 417 bio_dgram_data *data = (bio_dgram_data *)b->ptr; 418 clear_socket_error(); 419 420 if ( data->connected ) 421 ret=writesocket(b->num,in,inl); 422 else 423 { 424 int peerlen = sizeof(data->peer); 425 426 if (data->peer.sa.sa_family == AF_INET) 427 peerlen = sizeof(data->peer.sa_in); 428#if OPENSSL_USE_IPV6 429 else if (data->peer.sa.sa_family == AF_INET6) 430 peerlen = sizeof(data->peer.sa_in6); 431#endif 432#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) 433 ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen); 434#else 435 ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); 436#endif 437 } 438 439 BIO_clear_retry_flags(b); 440 if (ret <= 0) 441 { 442 if (BIO_dgram_should_retry(ret)) 443 { 444 BIO_set_retry_write(b); 445 data->_errno = get_last_socket_error(); 446 447#if 0 /* higher layers are responsible for querying MTU, if necessary */ 448 if ( data->_errno == EMSGSIZE) 449 /* retrieve the new MTU */ 450 BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); 451#endif 452 } 453 } 454 return(ret); 455 } 456 457static long dgram_get_mtu_overhead(bio_dgram_data *data) 458 { 459 long ret; 460 461 switch (data->peer.sa.sa_family) 462 { 463 case AF_INET: 464 /* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP */ 465 ret = 28; 466 break; 467#if OPENSSL_USE_IPV6 468 case AF_INET6: 469#ifdef IN6_IS_ADDR_V4MAPPED 470 if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) 471 /* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP */ 472 ret = 28; 473 else 474#endif 475 /* Assume this is UDP - 40 bytes for IP, 8 bytes for UDP */ 476 ret = 48; 477 break; 478#endif 479 default: 480 /* We don't know. Go with the historical default */ 481 ret = 28; 482 break; 483 } 484 return ret; 485 } 486 487static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) 488 { 489 long ret=1; 490 int *ip; 491 struct sockaddr *to = NULL; 492 bio_dgram_data *data = NULL; 493#if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU)) 494 int sockopt_val = 0; 495 socklen_t sockopt_len; /* assume that system supporting IP_MTU is 496 * modern enough to define socklen_t */ 497 socklen_t addr_len; 498 union { 499 struct sockaddr sa; 500 struct sockaddr_in s4; 501#if OPENSSL_USE_IPV6 502 struct sockaddr_in6 s6; 503#endif 504 } addr; 505#endif 506 507 data = (bio_dgram_data *)b->ptr; 508 509 switch (cmd) 510 { 511 case BIO_CTRL_RESET: 512 num=0; 513 case BIO_C_FILE_SEEK: 514 ret=0; 515 break; 516 case BIO_C_FILE_TELL: 517 case BIO_CTRL_INFO: 518 ret=0; 519 break; 520 case BIO_C_SET_FD: 521 dgram_clear(b); 522 b->num= *((int *)ptr); 523 b->shutdown=(int)num; 524 b->init=1; 525 break; 526 case BIO_C_GET_FD: 527 if (b->init) 528 { 529 ip=(int *)ptr; 530 if (ip != NULL) *ip=b->num; 531 ret=b->num; 532 } 533 else 534 ret= -1; 535 break; 536 case BIO_CTRL_GET_CLOSE: 537 ret=b->shutdown; 538 break; 539 case BIO_CTRL_SET_CLOSE: 540 b->shutdown=(int)num; 541 break; 542 case BIO_CTRL_PENDING: 543 case BIO_CTRL_WPENDING: 544 ret=0; 545 break; 546 case BIO_CTRL_DUP: 547 case BIO_CTRL_FLUSH: 548 ret=1; 549 break; 550 case BIO_CTRL_DGRAM_CONNECT: 551 to = (struct sockaddr *)ptr; 552#if 0 553 if (connect(b->num, to, sizeof(struct sockaddr)) < 0) 554 { perror("connect"); ret = 0; } 555 else 556 { 557#endif 558 switch (to->sa_family) 559 { 560 case AF_INET: 561 memcpy(&data->peer,to,sizeof(data->peer.sa_in)); 562 break; 563#if OPENSSL_USE_IPV6 564 case AF_INET6: 565 memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); 566 break; 567#endif 568 default: 569 memcpy(&data->peer,to,sizeof(data->peer.sa)); 570 break; 571 } 572#if 0 573 } 574#endif 575 break; 576 /* (Linux)kernel sets DF bit on outgoing IP packets */ 577 case BIO_CTRL_DGRAM_MTU_DISCOVER: 578#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) 579 addr_len = (socklen_t)sizeof(addr); 580 memset((void *)&addr, 0, sizeof(addr)); 581 if (getsockname(b->num, &addr.sa, &addr_len) < 0) 582 { 583 ret = 0; 584 break; 585 } 586 switch (addr.sa.sa_family) 587 { 588 case AF_INET: 589 sockopt_val = IP_PMTUDISC_DO; 590 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, 591 &sockopt_val, sizeof(sockopt_val))) < 0) 592 perror("setsockopt"); 593 break; 594#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) 595 case AF_INET6: 596 sockopt_val = IPV6_PMTUDISC_DO; 597 if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, 598 &sockopt_val, sizeof(sockopt_val))) < 0) 599 perror("setsockopt"); 600 break; 601#endif 602 default: 603 ret = -1; 604 break; 605 } 606 ret = -1; 607#else 608 break; 609#endif 610 case BIO_CTRL_DGRAM_QUERY_MTU: 611#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU) 612 addr_len = (socklen_t)sizeof(addr); 613 memset((void *)&addr, 0, sizeof(addr)); 614 if (getsockname(b->num, &addr.sa, &addr_len) < 0) 615 { 616 ret = 0; 617 break; 618 } 619 sockopt_len = sizeof(sockopt_val); 620 switch (addr.sa.sa_family) 621 { 622 case AF_INET: 623 if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, 624 &sockopt_len)) < 0 || sockopt_val < 0) 625 { 626 ret = 0; 627 } 628 else 629 { 630 /* we assume that the transport protocol is UDP and no 631 * IP options are used. 632 */ 633 data->mtu = sockopt_val - 8 - 20; 634 ret = data->mtu; 635 } 636 break; 637#if OPENSSL_USE_IPV6 && defined(IPV6_MTU) 638 case AF_INET6: 639 if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val, 640 &sockopt_len)) < 0 || sockopt_val < 0) 641 { 642 ret = 0; 643 } 644 else 645 { 646 /* we assume that the transport protocol is UDP and no 647 * IPV6 options are used. 648 */ 649 data->mtu = sockopt_val - 8 - 40; 650 ret = data->mtu; 651 } 652 break; 653#endif 654 default: 655 ret = 0; 656 break; 657 } 658#else 659 ret = 0; 660#endif 661 break; 662 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: 663 ret = -dgram_get_mtu_overhead(data); 664 switch (data->peer.sa.sa_family) 665 { 666 case AF_INET: 667 ret += 576; 668 break; 669#if OPENSSL_USE_IPV6 670 case AF_INET6: 671#ifdef IN6_IS_ADDR_V4MAPPED 672 if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) 673 ret += 576; 674 else 675#endif 676 ret += 1280; 677 break; 678#endif 679 default: 680 ret += 576; 681 break; 682 } 683 break; 684 case BIO_CTRL_DGRAM_GET_MTU: 685 return data->mtu; 686 break; 687 case BIO_CTRL_DGRAM_SET_MTU: 688 data->mtu = num; 689 ret = num; 690 break; 691 case BIO_CTRL_DGRAM_SET_CONNECTED: 692 to = (struct sockaddr *)ptr; 693 694 if ( to != NULL) 695 { 696 data->connected = 1; 697 switch (to->sa_family) 698 { 699 case AF_INET: 700 memcpy(&data->peer,to,sizeof(data->peer.sa_in)); 701 break; 702#if OPENSSL_USE_IPV6 703 case AF_INET6: 704 memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); 705 break; 706#endif 707 default: 708 memcpy(&data->peer,to,sizeof(data->peer.sa)); 709 break; 710 } 711 } 712 else 713 { 714 data->connected = 0; 715 memset(&(data->peer), 0x00, sizeof(data->peer)); 716 } 717 break; 718 case BIO_CTRL_DGRAM_GET_PEER: 719 switch (data->peer.sa.sa_family) 720 { 721 case AF_INET: 722 ret=sizeof(data->peer.sa_in); 723 break; 724#if OPENSSL_USE_IPV6 725 case AF_INET6: 726 ret=sizeof(data->peer.sa_in6); 727 break; 728#endif 729 default: 730 ret=sizeof(data->peer.sa); 731 break; 732 } 733 if (num==0 || num>ret) 734 num=ret; 735 memcpy(ptr,&data->peer,(ret=num)); 736 break; 737 case BIO_CTRL_DGRAM_SET_PEER: 738 to = (struct sockaddr *) ptr; 739 switch (to->sa_family) 740 { 741 case AF_INET: 742 memcpy(&data->peer,to,sizeof(data->peer.sa_in)); 743 break; 744#if OPENSSL_USE_IPV6 745 case AF_INET6: 746 memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); 747 break; 748#endif 749 default: 750 memcpy(&data->peer,to,sizeof(data->peer.sa)); 751 break; 752 } 753 break; 754 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: 755 memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); 756 break; 757#if defined(SO_RCVTIMEO) 758 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: 759#ifdef OPENSSL_SYS_WINDOWS 760 { 761 struct timeval *tv = (struct timeval *)ptr; 762 int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; 763 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 764 (void*)&timeout, sizeof(timeout)) < 0) 765 { perror("setsockopt"); ret = -1; } 766 } 767#else 768 if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, 769 sizeof(struct timeval)) < 0) 770 { perror("setsockopt"); ret = -1; } 771#endif 772 break; 773 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: 774 { 775 union { size_t s; int i; } sz = {0}; 776#ifdef OPENSSL_SYS_WINDOWS 777 int timeout; 778 struct timeval *tv = (struct timeval *)ptr; 779 780 sz.i = sizeof(timeout); 781 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 782 (void*)&timeout, &sz.i) < 0) 783 { perror("getsockopt"); ret = -1; } 784 else 785 { 786 tv->tv_sec = timeout / 1000; 787 tv->tv_usec = (timeout % 1000) * 1000; 788 ret = sizeof(*tv); 789 } 790#else 791 sz.i = sizeof(struct timeval); 792 if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 793 ptr, (void *)&sz) < 0) 794 { perror("getsockopt"); ret = -1; } 795 else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) 796 { 797 OPENSSL_assert(sz.s<=sizeof(struct timeval)); 798 ret = (int)sz.s; 799 } 800 else 801 ret = sz.i; 802#endif 803 } 804 break; 805#endif 806#if defined(SO_SNDTIMEO) 807 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: 808#ifdef OPENSSL_SYS_WINDOWS 809 { 810 struct timeval *tv = (struct timeval *)ptr; 811 int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; 812 if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 813 (void*)&timeout, sizeof(timeout)) < 0) 814 { perror("setsockopt"); ret = -1; } 815 } 816#else 817 if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, 818 sizeof(struct timeval)) < 0) 819 { perror("setsockopt"); ret = -1; } 820#endif 821 break; 822 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: 823 { 824 union { size_t s; int i; } sz = {0}; 825#ifdef OPENSSL_SYS_WINDOWS 826 int timeout; 827 struct timeval *tv = (struct timeval *)ptr; 828 829 sz.i = sizeof(timeout); 830 if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 831 (void*)&timeout, &sz.i) < 0) 832 { perror("getsockopt"); ret = -1; } 833 else 834 { 835 tv->tv_sec = timeout / 1000; 836 tv->tv_usec = (timeout % 1000) * 1000; 837 ret = sizeof(*tv); 838 } 839#else 840 sz.i = sizeof(struct timeval); 841 if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 842 ptr, (void *)&sz) < 0) 843 { perror("getsockopt"); ret = -1; } 844 else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) 845 { 846 OPENSSL_assert(sz.s<=sizeof(struct timeval)); 847 ret = (int)sz.s; 848 } 849 else 850 ret = sz.i; 851#endif 852 } 853 break; 854#endif 855 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: 856 /* fall-through */ 857 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: 858#ifdef OPENSSL_SYS_WINDOWS 859 if ( data->_errno == WSAETIMEDOUT) 860#else 861 if ( data->_errno == EAGAIN) 862#endif 863 { 864 ret = 1; 865 data->_errno = 0; 866 } 867 else 868 ret = 0; 869 break; 870#ifdef EMSGSIZE 871 case BIO_CTRL_DGRAM_MTU_EXCEEDED: 872 if ( data->_errno == EMSGSIZE) 873 { 874 ret = 1; 875 data->_errno = 0; 876 } 877 else 878 ret = 0; 879 break; 880#endif 881 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: 882 ret = dgram_get_mtu_overhead(data); 883 break; 884 default: 885 ret=0; 886 break; 887 } 888 return(ret); 889 } 890 891static int dgram_puts(BIO *bp, const char *str) 892 { 893 int n,ret; 894 895 n=strlen(str); 896 ret=dgram_write(bp,str,n); 897 return(ret); 898 } 899 900#ifndef OPENSSL_NO_SCTP 901BIO_METHOD *BIO_s_datagram_sctp(void) 902 { 903 return(&methods_dgramp_sctp); 904 } 905 906BIO *BIO_new_dgram_sctp(int fd, int close_flag) 907 { 908 BIO *bio; 909 int ret, optval = 20000; 910 int auth_data = 0, auth_forward = 0; 911 unsigned char *p; 912 struct sctp_authchunk auth; 913 struct sctp_authchunks *authchunks; 914 socklen_t sockopt_len; 915#ifdef SCTP_AUTHENTICATION_EVENT 916#ifdef SCTP_EVENT 917 struct sctp_event event; 918#else 919 struct sctp_event_subscribe event; 920#endif 921#endif 922 923 bio=BIO_new(BIO_s_datagram_sctp()); 924 if (bio == NULL) return(NULL); 925 BIO_set_fd(bio,fd,close_flag); 926 927 /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */ 928 auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE; 929 ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk)); 930 if (ret < 0) 931 { 932 BIO_vfree(bio); 933 return(NULL); 934 } 935 auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE; 936 ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk)); 937 if (ret < 0) 938 { 939 BIO_vfree(bio); 940 return(NULL); 941 } 942 943 /* Test if activation was successful. When using accept(), 944 * SCTP-AUTH has to be activated for the listening socket 945 * already, otherwise the connected socket won't use it. */ 946 sockopt_len = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); 947 authchunks = OPENSSL_malloc(sockopt_len); 948 memset(authchunks, 0, sizeof(sockopt_len)); 949 ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, &sockopt_len); 950 951 if (ret < 0) 952 { 953 OPENSSL_free(authchunks); 954 BIO_vfree(bio); 955 return(NULL); 956 } 957 958 for (p = (unsigned char*) authchunks->gauth_chunks; 959 p < (unsigned char*) authchunks + sockopt_len; 960 p += sizeof(uint8_t)) 961 { 962 if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1; 963 if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1; 964 } 965 966 OPENSSL_free(authchunks); 967 968 OPENSSL_assert(auth_data); 969 OPENSSL_assert(auth_forward); 970 971#ifdef SCTP_AUTHENTICATION_EVENT 972#ifdef SCTP_EVENT 973 memset(&event, 0, sizeof(struct sctp_event)); 974 event.se_assoc_id = 0; 975 event.se_type = SCTP_AUTHENTICATION_EVENT; 976 event.se_on = 1; 977 ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); 978 if (ret < 0) 979 { 980 BIO_vfree(bio); 981 return(NULL); 982 } 983#else 984 sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe); 985 ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len); 986 if (ret < 0) 987 { 988 BIO_vfree(bio); 989 return(NULL); 990 } 991 992 event.sctp_authentication_event = 1; 993 994 ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 995 if (ret < 0) 996 { 997 BIO_vfree(bio); 998 return(NULL); 999 } 1000#endif 1001#endif 1002 1003 /* Disable partial delivery by setting the min size 1004 * larger than the max record size of 2^14 + 2048 + 13 1005 */ 1006 ret = setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, sizeof(optval)); 1007 if (ret < 0) 1008 { 1009 BIO_vfree(bio); 1010 return(NULL); 1011 } 1012 1013 return(bio); 1014 } 1015 1016int BIO_dgram_is_sctp(BIO *bio) 1017 { 1018 return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP); 1019 } 1020 1021static int dgram_sctp_new(BIO *bi) 1022 { 1023 bio_dgram_sctp_data *data = NULL; 1024 1025 bi->init=0; 1026 bi->num=0; 1027 data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data)); 1028 if (data == NULL) 1029 return 0; 1030 memset(data, 0x00, sizeof(bio_dgram_sctp_data)); 1031#ifdef SCTP_PR_SCTP_NONE 1032 data->prinfo.pr_policy = SCTP_PR_SCTP_NONE; 1033#endif 1034 bi->ptr = data; 1035 1036 bi->flags=0; 1037 return(1); 1038 } 1039 1040static int dgram_sctp_free(BIO *a) 1041 { 1042 bio_dgram_sctp_data *data; 1043 1044 if (a == NULL) return(0); 1045 if ( ! dgram_clear(a)) 1046 return 0; 1047 1048 data = (bio_dgram_sctp_data *)a->ptr; 1049 if(data != NULL) 1050 { 1051 if(data->saved_message.data != NULL) 1052 OPENSSL_free(data->saved_message.data); 1053 OPENSSL_free(data); 1054 } 1055 1056 return(1); 1057 } 1058 1059#ifdef SCTP_AUTHENTICATION_EVENT 1060void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp) 1061 { 1062 int ret; 1063 struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event; 1064 1065 if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) 1066 { 1067 struct sctp_authkeyid authkeyid; 1068 1069 /* delete key */ 1070 authkeyid.scact_keynumber = authkeyevent->auth_keynumber; 1071 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, 1072 &authkeyid, sizeof(struct sctp_authkeyid)); 1073 } 1074 } 1075#endif 1076 1077static int dgram_sctp_read(BIO *b, char *out, int outl) 1078 { 1079 int ret = 0, n = 0, i, optval; 1080 socklen_t optlen; 1081 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 1082 union sctp_notification *snp; 1083 struct msghdr msg; 1084 struct iovec iov; 1085 struct cmsghdr *cmsg; 1086 char cmsgbuf[512]; 1087 1088 if (out != NULL) 1089 { 1090 clear_socket_error(); 1091 1092 do 1093 { 1094 memset(&data->rcvinfo, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo)); 1095 iov.iov_base = out; 1096 iov.iov_len = outl; 1097 msg.msg_name = NULL; 1098 msg.msg_namelen = 0; 1099 msg.msg_iov = &iov; 1100 msg.msg_iovlen = 1; 1101 msg.msg_control = cmsgbuf; 1102 msg.msg_controllen = 512; 1103 msg.msg_flags = 0; 1104 n = recvmsg(b->num, &msg, 0); 1105 1106 if (n <= 0) 1107 { 1108 if (n < 0) 1109 ret = n; 1110 break; 1111 } 1112 1113 if (msg.msg_controllen > 0) 1114 { 1115 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) 1116 { 1117 if (cmsg->cmsg_level != IPPROTO_SCTP) 1118 continue; 1119#ifdef SCTP_RCVINFO 1120 if (cmsg->cmsg_type == SCTP_RCVINFO) 1121 { 1122 struct sctp_rcvinfo *rcvinfo; 1123 1124 rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg); 1125 data->rcvinfo.rcv_sid = rcvinfo->rcv_sid; 1126 data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn; 1127 data->rcvinfo.rcv_flags = rcvinfo->rcv_flags; 1128 data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid; 1129 data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn; 1130 data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn; 1131 data->rcvinfo.rcv_context = rcvinfo->rcv_context; 1132 } 1133#endif 1134#ifdef SCTP_SNDRCV 1135 if (cmsg->cmsg_type == SCTP_SNDRCV) 1136 { 1137 struct sctp_sndrcvinfo *sndrcvinfo; 1138 1139 sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); 1140 data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream; 1141 data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn; 1142 data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags; 1143 data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid; 1144 data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn; 1145 data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn; 1146 data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context; 1147 } 1148#endif 1149 } 1150 } 1151 1152 if (msg.msg_flags & MSG_NOTIFICATION) 1153 { 1154 snp = (union sctp_notification*) out; 1155 if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) 1156 { 1157#ifdef SCTP_EVENT 1158 struct sctp_event event; 1159#else 1160 struct sctp_event_subscribe event; 1161 socklen_t eventsize; 1162#endif 1163 /* If a message has been delayed until the socket 1164 * is dry, it can be sent now. 1165 */ 1166 if (data->saved_message.length > 0) 1167 { 1168 dgram_sctp_write(data->saved_message.bio, data->saved_message.data, 1169 data->saved_message.length); 1170 OPENSSL_free(data->saved_message.data); 1171 data->saved_message.data = NULL; 1172 data->saved_message.length = 0; 1173 } 1174 1175 /* disable sender dry event */ 1176#ifdef SCTP_EVENT 1177 memset(&event, 0, sizeof(struct sctp_event)); 1178 event.se_assoc_id = 0; 1179 event.se_type = SCTP_SENDER_DRY_EVENT; 1180 event.se_on = 0; 1181 i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); 1182 if (i < 0) 1183 { 1184 ret = i; 1185 break; 1186 } 1187#else 1188 eventsize = sizeof(struct sctp_event_subscribe); 1189 i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); 1190 if (i < 0) 1191 { 1192 ret = i; 1193 break; 1194 } 1195 1196 event.sctp_sender_dry_event = 0; 1197 1198 i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 1199 if (i < 0) 1200 { 1201 ret = i; 1202 break; 1203 } 1204#endif 1205 } 1206 1207#ifdef SCTP_AUTHENTICATION_EVENT 1208 if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) 1209 dgram_sctp_handle_auth_free_key_event(b, snp); 1210#endif 1211 1212 if (data->handle_notifications != NULL) 1213 data->handle_notifications(b, data->notification_context, (void*) out); 1214 1215 memset(out, 0, outl); 1216 } 1217 else 1218 ret += n; 1219 } 1220 while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl)); 1221 1222 if (ret > 0 && !(msg.msg_flags & MSG_EOR)) 1223 { 1224 /* Partial message read, this should never happen! */ 1225 1226 /* The buffer was too small, this means the peer sent 1227 * a message that was larger than allowed. */ 1228 if (ret == outl) 1229 return -1; 1230 1231 /* Test if socket buffer can handle max record 1232 * size (2^14 + 2048 + 13) 1233 */ 1234 optlen = (socklen_t) sizeof(int); 1235 ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen); 1236 if (ret >= 0) 1237 OPENSSL_assert(optval >= 18445); 1238 1239 /* Test if SCTP doesn't partially deliver below 1240 * max record size (2^14 + 2048 + 13) 1241 */ 1242 optlen = (socklen_t) sizeof(int); 1243 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, 1244 &optval, &optlen); 1245 if (ret >= 0) 1246 OPENSSL_assert(optval >= 18445); 1247 1248 /* Partially delivered notification??? Probably a bug.... */ 1249 OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION)); 1250 1251 /* Everything seems ok till now, so it's most likely 1252 * a message dropped by PR-SCTP. 1253 */ 1254 memset(out, 0, outl); 1255 BIO_set_retry_read(b); 1256 return -1; 1257 } 1258 1259 BIO_clear_retry_flags(b); 1260 if (ret < 0) 1261 { 1262 if (BIO_dgram_should_retry(ret)) 1263 { 1264 BIO_set_retry_read(b); 1265 data->_errno = get_last_socket_error(); 1266 } 1267 } 1268 1269 /* Test if peer uses SCTP-AUTH before continuing */ 1270 if (!data->peer_auth_tested) 1271 { 1272 int ii, auth_data = 0, auth_forward = 0; 1273 unsigned char *p; 1274 struct sctp_authchunks *authchunks; 1275 1276 optlen = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); 1277 authchunks = OPENSSL_malloc(optlen); 1278 memset(authchunks, 0, sizeof(optlen)); 1279 ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen); 1280 1281 if (ii >= 0) 1282 for (p = (unsigned char*) authchunks->gauth_chunks; 1283 p < (unsigned char*) authchunks + optlen; 1284 p += sizeof(uint8_t)) 1285 { 1286 if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1; 1287 if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1; 1288 } 1289 1290 OPENSSL_free(authchunks); 1291 1292 if (!auth_data || !auth_forward) 1293 { 1294 BIOerr(BIO_F_DGRAM_SCTP_READ,BIO_R_CONNECT_ERROR); 1295 return -1; 1296 } 1297 1298 data->peer_auth_tested = 1; 1299 } 1300 } 1301 return(ret); 1302 } 1303 1304static int dgram_sctp_write(BIO *b, const char *in, int inl) 1305 { 1306 int ret; 1307 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 1308 struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo); 1309 struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo); 1310 struct bio_dgram_sctp_sndinfo handshake_sinfo; 1311 struct iovec iov[1]; 1312 struct msghdr msg; 1313 struct cmsghdr *cmsg; 1314#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO) 1315 char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + CMSG_SPACE(sizeof(struct sctp_prinfo))]; 1316 struct sctp_sndinfo *sndinfo; 1317 struct sctp_prinfo *prinfo; 1318#else 1319 char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; 1320 struct sctp_sndrcvinfo *sndrcvinfo; 1321#endif 1322 1323 clear_socket_error(); 1324 1325 /* If we're send anything else than application data, 1326 * disable all user parameters and flags. 1327 */ 1328 if (in[0] != 23) { 1329 memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo)); 1330#ifdef SCTP_SACK_IMMEDIATELY 1331 handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY; 1332#endif 1333 sinfo = &handshake_sinfo; 1334 } 1335 1336 /* If we have to send a shutdown alert message and the 1337 * socket is not dry yet, we have to save it and send it 1338 * as soon as the socket gets dry. 1339 */ 1340 if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) 1341 { 1342 data->saved_message.bio = b; 1343 if (data->saved_message.data) 1344 OPENSSL_free(data->saved_message.data); 1345 data->saved_message.data = OPENSSL_malloc(inl); 1346 memcpy(data->saved_message.data, in, inl); 1347 data->saved_message.length = inl; 1348 return inl; 1349 } 1350 1351 iov[0].iov_base = (char *)in; 1352 iov[0].iov_len = inl; 1353 msg.msg_name = NULL; 1354 msg.msg_namelen = 0; 1355 msg.msg_iov = iov; 1356 msg.msg_iovlen = 1; 1357 msg.msg_control = (caddr_t)cmsgbuf; 1358 msg.msg_controllen = 0; 1359 msg.msg_flags = 0; 1360#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO) 1361 cmsg = (struct cmsghdr *)cmsgbuf; 1362 cmsg->cmsg_level = IPPROTO_SCTP; 1363 cmsg->cmsg_type = SCTP_SNDINFO; 1364 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo)); 1365 sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg); 1366 memset(sndinfo, 0, sizeof(struct sctp_sndinfo)); 1367 sndinfo->snd_sid = sinfo->snd_sid; 1368 sndinfo->snd_flags = sinfo->snd_flags; 1369 sndinfo->snd_ppid = sinfo->snd_ppid; 1370 sndinfo->snd_context = sinfo->snd_context; 1371 msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo)); 1372 1373 cmsg = (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))]; 1374 cmsg->cmsg_level = IPPROTO_SCTP; 1375 cmsg->cmsg_type = SCTP_PRINFO; 1376 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo)); 1377 prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg); 1378 memset(prinfo, 0, sizeof(struct sctp_prinfo)); 1379 prinfo->pr_policy = pinfo->pr_policy; 1380 prinfo->pr_value = pinfo->pr_value; 1381 msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo)); 1382#else 1383 cmsg = (struct cmsghdr *)cmsgbuf; 1384 cmsg->cmsg_level = IPPROTO_SCTP; 1385 cmsg->cmsg_type = SCTP_SNDRCV; 1386 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); 1387 sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); 1388 memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); 1389 sndrcvinfo->sinfo_stream = sinfo->snd_sid; 1390 sndrcvinfo->sinfo_flags = sinfo->snd_flags; 1391#ifdef __FreeBSD__ 1392 sndrcvinfo->sinfo_flags |= pinfo->pr_policy; 1393#endif 1394 sndrcvinfo->sinfo_ppid = sinfo->snd_ppid; 1395 sndrcvinfo->sinfo_context = sinfo->snd_context; 1396 sndrcvinfo->sinfo_timetolive = pinfo->pr_value; 1397 msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)); 1398#endif 1399 1400 ret = sendmsg(b->num, &msg, 0); 1401 1402 BIO_clear_retry_flags(b); 1403 if (ret <= 0) 1404 { 1405 if (BIO_dgram_should_retry(ret)) 1406 { 1407 BIO_set_retry_write(b); 1408 data->_errno = get_last_socket_error(); 1409 } 1410 } 1411 return(ret); 1412 } 1413 1414static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) 1415 { 1416 long ret=1; 1417 bio_dgram_sctp_data *data = NULL; 1418 socklen_t sockopt_len = 0; 1419 struct sctp_authkeyid authkeyid; 1420 struct sctp_authkey *authkey = NULL; 1421 1422 data = (bio_dgram_sctp_data *)b->ptr; 1423 1424 switch (cmd) 1425 { 1426 case BIO_CTRL_DGRAM_QUERY_MTU: 1427 /* Set to maximum (2^14) 1428 * and ignore user input to enable transport 1429 * protocol fragmentation. 1430 * Returns always 2^14. 1431 */ 1432 data->mtu = 16384; 1433 ret = data->mtu; 1434 break; 1435 case BIO_CTRL_DGRAM_SET_MTU: 1436 /* Set to maximum (2^14) 1437 * and ignore input to enable transport 1438 * protocol fragmentation. 1439 * Returns always 2^14. 1440 */ 1441 data->mtu = 16384; 1442 ret = data->mtu; 1443 break; 1444 case BIO_CTRL_DGRAM_SET_CONNECTED: 1445 case BIO_CTRL_DGRAM_CONNECT: 1446 /* Returns always -1. */ 1447 ret = -1; 1448 break; 1449 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: 1450 /* SCTP doesn't need the DTLS timer 1451 * Returns always 1. 1452 */ 1453 break; 1454 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: 1455 /* We allow transport protocol fragmentation so this is irrelevant */ 1456 ret = 0; 1457 break; 1458 case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE: 1459 if (num > 0) 1460 data->in_handshake = 1; 1461 else 1462 data->in_handshake = 0; 1463 1464 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY, &data->in_handshake, sizeof(int)); 1465 break; 1466 case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY: 1467 /* New shared key for SCTP AUTH. 1468 * Returns 0 on success, -1 otherwise. 1469 */ 1470 1471 /* Get active key */ 1472 sockopt_len = sizeof(struct sctp_authkeyid); 1473 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len); 1474 if (ret < 0) break; 1475 1476 /* Add new key */ 1477 sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t); 1478 authkey = OPENSSL_malloc(sockopt_len); 1479 if (authkey == NULL) 1480 { 1481 ret = -1; 1482 break; 1483 } 1484 memset(authkey, 0x00, sockopt_len); 1485 authkey->sca_keynumber = authkeyid.scact_keynumber + 1; 1486#ifndef __FreeBSD__ 1487 /* This field is missing in FreeBSD 8.2 and earlier, 1488 * and FreeBSD 8.3 and higher work without it. 1489 */ 1490 authkey->sca_keylength = 64; 1491#endif 1492 memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t)); 1493 1494 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len); 1495 OPENSSL_free(authkey); 1496 authkey = NULL; 1497 if (ret < 0) break; 1498 1499 /* Reset active key */ 1500 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, 1501 &authkeyid, sizeof(struct sctp_authkeyid)); 1502 if (ret < 0) break; 1503 1504 break; 1505 case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY: 1506 /* Returns 0 on success, -1 otherwise. */ 1507 1508 /* Get active key */ 1509 sockopt_len = sizeof(struct sctp_authkeyid); 1510 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len); 1511 if (ret < 0) break; 1512 1513 /* Set active key */ 1514 authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1; 1515 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, 1516 &authkeyid, sizeof(struct sctp_authkeyid)); 1517 if (ret < 0) break; 1518 1519 /* CCS has been sent, so remember that and fall through 1520 * to check if we need to deactivate an old key 1521 */ 1522 data->ccs_sent = 1; 1523 1524 case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD: 1525 /* Returns 0 on success, -1 otherwise. */ 1526 1527 /* Has this command really been called or is this just a fall-through? */ 1528 if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD) 1529 data->ccs_rcvd = 1; 1530 1531 /* CSS has been both, received and sent, so deactivate an old key */ 1532 if (data->ccs_rcvd == 1 && data->ccs_sent == 1) 1533 { 1534 /* Get active key */ 1535 sockopt_len = sizeof(struct sctp_authkeyid); 1536 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len); 1537 if (ret < 0) break; 1538 1539 /* Deactivate key or delete second last key if 1540 * SCTP_AUTHENTICATION_EVENT is not available. 1541 */ 1542 authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; 1543#ifdef SCTP_AUTH_DEACTIVATE_KEY 1544 sockopt_len = sizeof(struct sctp_authkeyid); 1545 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY, 1546 &authkeyid, sockopt_len); 1547 if (ret < 0) break; 1548#endif 1549#ifndef SCTP_AUTHENTICATION_EVENT 1550 if (authkeyid.scact_keynumber > 0) 1551 { 1552 authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; 1553 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, 1554 &authkeyid, sizeof(struct sctp_authkeyid)); 1555 if (ret < 0) break; 1556 } 1557#endif 1558 1559 data->ccs_rcvd = 0; 1560 data->ccs_sent = 0; 1561 } 1562 break; 1563 case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO: 1564 /* Returns the size of the copied struct. */ 1565 if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo)) 1566 num = sizeof(struct bio_dgram_sctp_sndinfo); 1567 1568 memcpy(ptr, &(data->sndinfo), num); 1569 ret = num; 1570 break; 1571 case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO: 1572 /* Returns the size of the copied struct. */ 1573 if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo)) 1574 num = sizeof(struct bio_dgram_sctp_sndinfo); 1575 1576 memcpy(&(data->sndinfo), ptr, num); 1577 break; 1578 case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO: 1579 /* Returns the size of the copied struct. */ 1580 if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo)) 1581 num = sizeof(struct bio_dgram_sctp_rcvinfo); 1582 1583 memcpy(ptr, &data->rcvinfo, num); 1584 1585 ret = num; 1586 break; 1587 case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO: 1588 /* Returns the size of the copied struct. */ 1589 if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo)) 1590 num = sizeof(struct bio_dgram_sctp_rcvinfo); 1591 1592 memcpy(&(data->rcvinfo), ptr, num); 1593 break; 1594 case BIO_CTRL_DGRAM_SCTP_GET_PRINFO: 1595 /* Returns the size of the copied struct. */ 1596 if (num > (long) sizeof(struct bio_dgram_sctp_prinfo)) 1597 num = sizeof(struct bio_dgram_sctp_prinfo); 1598 1599 memcpy(ptr, &(data->prinfo), num); 1600 ret = num; 1601 break; 1602 case BIO_CTRL_DGRAM_SCTP_SET_PRINFO: 1603 /* Returns the size of the copied struct. */ 1604 if (num > (long) sizeof(struct bio_dgram_sctp_prinfo)) 1605 num = sizeof(struct bio_dgram_sctp_prinfo); 1606 1607 memcpy(&(data->prinfo), ptr, num); 1608 break; 1609 case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN: 1610 /* Returns always 1. */ 1611 if (num > 0) 1612 data->save_shutdown = 1; 1613 else 1614 data->save_shutdown = 0; 1615 break; 1616 1617 default: 1618 /* Pass to default ctrl function to 1619 * process SCTP unspecific commands 1620 */ 1621 ret=dgram_ctrl(b, cmd, num, ptr); 1622 break; 1623 } 1624 return(ret); 1625 } 1626 1627int BIO_dgram_sctp_notification_cb(BIO *b, 1628 void (*handle_notifications)(BIO *bio, void *context, void *buf), 1629 void *context) 1630 { 1631 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; 1632 1633 if (handle_notifications != NULL) 1634 { 1635 data->handle_notifications = handle_notifications; 1636 data->notification_context = context; 1637 } 1638 else 1639 return -1; 1640 1641 return 0; 1642 } 1643 1644int BIO_dgram_sctp_wait_for_dry(BIO *b) 1645{ 1646 int is_dry = 0; 1647 int n, sockflags, ret; 1648 union sctp_notification snp; 1649 struct msghdr msg; 1650 struct iovec iov; 1651#ifdef SCTP_EVENT 1652 struct sctp_event event; 1653#else 1654 struct sctp_event_subscribe event; 1655 socklen_t eventsize; 1656#endif 1657 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 1658 1659 /* set sender dry event */ 1660#ifdef SCTP_EVENT 1661 memset(&event, 0, sizeof(struct sctp_event)); 1662 event.se_assoc_id = 0; 1663 event.se_type = SCTP_SENDER_DRY_EVENT; 1664 event.se_on = 1; 1665 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); 1666#else 1667 eventsize = sizeof(struct sctp_event_subscribe); 1668 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); 1669 if (ret < 0) 1670 return -1; 1671 1672 event.sctp_sender_dry_event = 1; 1673 1674 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 1675#endif 1676 if (ret < 0) 1677 return -1; 1678 1679 /* peek for notification */ 1680 memset(&snp, 0x00, sizeof(union sctp_notification)); 1681 iov.iov_base = (char *)&snp; 1682 iov.iov_len = sizeof(union sctp_notification); 1683 msg.msg_name = NULL; 1684 msg.msg_namelen = 0; 1685 msg.msg_iov = &iov; 1686 msg.msg_iovlen = 1; 1687 msg.msg_control = NULL; 1688 msg.msg_controllen = 0; 1689 msg.msg_flags = 0; 1690 1691 n = recvmsg(b->num, &msg, MSG_PEEK); 1692 if (n <= 0) 1693 { 1694 if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK)) 1695 return -1; 1696 else 1697 return 0; 1698 } 1699 1700 /* if we find a notification, process it and try again if necessary */ 1701 while (msg.msg_flags & MSG_NOTIFICATION) 1702 { 1703 memset(&snp, 0x00, sizeof(union sctp_notification)); 1704 iov.iov_base = (char *)&snp; 1705 iov.iov_len = sizeof(union sctp_notification); 1706 msg.msg_name = NULL; 1707 msg.msg_namelen = 0; 1708 msg.msg_iov = &iov; 1709 msg.msg_iovlen = 1; 1710 msg.msg_control = NULL; 1711 msg.msg_controllen = 0; 1712 msg.msg_flags = 0; 1713 1714 n = recvmsg(b->num, &msg, 0); 1715 if (n <= 0) 1716 { 1717 if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK)) 1718 return -1; 1719 else 1720 return is_dry; 1721 } 1722 1723 if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) 1724 { 1725 is_dry = 1; 1726 1727 /* disable sender dry event */ 1728#ifdef SCTP_EVENT 1729 memset(&event, 0, sizeof(struct sctp_event)); 1730 event.se_assoc_id = 0; 1731 event.se_type = SCTP_SENDER_DRY_EVENT; 1732 event.se_on = 0; 1733 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); 1734#else 1735 eventsize = (socklen_t) sizeof(struct sctp_event_subscribe); 1736 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); 1737 if (ret < 0) 1738 return -1; 1739 1740 event.sctp_sender_dry_event = 0; 1741 1742 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 1743#endif 1744 if (ret < 0) 1745 return -1; 1746 } 1747 1748#ifdef SCTP_AUTHENTICATION_EVENT 1749 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) 1750 dgram_sctp_handle_auth_free_key_event(b, &snp); 1751#endif 1752 1753 if (data->handle_notifications != NULL) 1754 data->handle_notifications(b, data->notification_context, (void*) &snp); 1755 1756 /* found notification, peek again */ 1757 memset(&snp, 0x00, sizeof(union sctp_notification)); 1758 iov.iov_base = (char *)&snp; 1759 iov.iov_len = sizeof(union sctp_notification); 1760 msg.msg_name = NULL; 1761 msg.msg_namelen = 0; 1762 msg.msg_iov = &iov; 1763 msg.msg_iovlen = 1; 1764 msg.msg_control = NULL; 1765 msg.msg_controllen = 0; 1766 msg.msg_flags = 0; 1767 1768 /* if we have seen the dry already, don't wait */ 1769 if (is_dry) 1770 { 1771 sockflags = fcntl(b->num, F_GETFL, 0); 1772 fcntl(b->num, F_SETFL, O_NONBLOCK); 1773 } 1774 1775 n = recvmsg(b->num, &msg, MSG_PEEK); 1776 1777 if (is_dry) 1778 { 1779 fcntl(b->num, F_SETFL, sockflags); 1780 } 1781 1782 if (n <= 0) 1783 { 1784 if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK)) 1785 return -1; 1786 else 1787 return is_dry; 1788 } 1789 } 1790 1791 /* read anything else */ 1792 return is_dry; 1793} 1794 1795int BIO_dgram_sctp_msg_waiting(BIO *b) 1796 { 1797 int n, sockflags; 1798 union sctp_notification snp; 1799 struct msghdr msg; 1800 struct iovec iov; 1801 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 1802 1803 /* Check if there are any messages waiting to be read */ 1804 do 1805 { 1806 memset(&snp, 0x00, sizeof(union sctp_notification)); 1807 iov.iov_base = (char *)&snp; 1808 iov.iov_len = sizeof(union sctp_notification); 1809 msg.msg_name = NULL; 1810 msg.msg_namelen = 0; 1811 msg.msg_iov = &iov; 1812 msg.msg_iovlen = 1; 1813 msg.msg_control = NULL; 1814 msg.msg_controllen = 0; 1815 msg.msg_flags = 0; 1816 1817 sockflags = fcntl(b->num, F_GETFL, 0); 1818 fcntl(b->num, F_SETFL, O_NONBLOCK); 1819 n = recvmsg(b->num, &msg, MSG_PEEK); 1820 fcntl(b->num, F_SETFL, sockflags); 1821 1822 /* if notification, process and try again */ 1823 if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) 1824 { 1825#ifdef SCTP_AUTHENTICATION_EVENT 1826 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) 1827 dgram_sctp_handle_auth_free_key_event(b, &snp); 1828#endif 1829 1830 memset(&snp, 0x00, sizeof(union sctp_notification)); 1831 iov.iov_base = (char *)&snp; 1832 iov.iov_len = sizeof(union sctp_notification); 1833 msg.msg_name = NULL; 1834 msg.msg_namelen = 0; 1835 msg.msg_iov = &iov; 1836 msg.msg_iovlen = 1; 1837 msg.msg_control = NULL; 1838 msg.msg_controllen = 0; 1839 msg.msg_flags = 0; 1840 n = recvmsg(b->num, &msg, 0); 1841 1842 if (data->handle_notifications != NULL) 1843 data->handle_notifications(b, data->notification_context, (void*) &snp); 1844 } 1845 1846 } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)); 1847 1848 /* Return 1 if there is a message to be read, return 0 otherwise. */ 1849 if (n > 0) 1850 return 1; 1851 else 1852 return 0; 1853 } 1854 1855static int dgram_sctp_puts(BIO *bp, const char *str) 1856 { 1857 int n,ret; 1858 1859 n=strlen(str); 1860 ret=dgram_sctp_write(bp,str,n); 1861 return(ret); 1862 } 1863#endif 1864 1865static int BIO_dgram_should_retry(int i) 1866 { 1867 int err; 1868 1869 if ((i == 0) || (i == -1)) 1870 { 1871 err=get_last_socket_error(); 1872 1873#if defined(OPENSSL_SYS_WINDOWS) 1874 /* If the socket return value (i) is -1 1875 * and err is unexpectedly 0 at this point, 1876 * the error code was overwritten by 1877 * another system call before this error 1878 * handling is called. 1879 */ 1880#endif 1881 1882 return(BIO_dgram_non_fatal_error(err)); 1883 } 1884 return(0); 1885 } 1886 1887int BIO_dgram_non_fatal_error(int err) 1888 { 1889 switch (err) 1890 { 1891#if defined(OPENSSL_SYS_WINDOWS) 1892# if defined(WSAEWOULDBLOCK) 1893 case WSAEWOULDBLOCK: 1894# endif 1895 1896# if 0 /* This appears to always be an error */ 1897# if defined(WSAENOTCONN) 1898 case WSAENOTCONN: 1899# endif 1900# endif 1901#endif 1902 1903#ifdef EWOULDBLOCK 1904# ifdef WSAEWOULDBLOCK 1905# if WSAEWOULDBLOCK != EWOULDBLOCK 1906 case EWOULDBLOCK: 1907# endif 1908# else 1909 case EWOULDBLOCK: 1910# endif 1911#endif 1912 1913#ifdef EINTR 1914 case EINTR: 1915#endif 1916 1917#ifdef EAGAIN 1918#if EWOULDBLOCK != EAGAIN 1919 case EAGAIN: 1920# endif 1921#endif 1922 1923#ifdef EPROTO 1924 case EPROTO: 1925#endif 1926 1927#ifdef EINPROGRESS 1928 case EINPROGRESS: 1929#endif 1930 1931#ifdef EALREADY 1932 case EALREADY: 1933#endif 1934 1935 return(1); 1936 /* break; */ 1937 default: 1938 break; 1939 } 1940 return(0); 1941 } 1942 1943static void get_current_time(struct timeval *t) 1944 { 1945#ifdef OPENSSL_SYS_WIN32 1946 struct _timeb tb; 1947 _ftime(&tb); 1948 t->tv_sec = (long)tb.time; 1949 t->tv_usec = (long)tb.millitm * 1000; 1950#elif defined(OPENSSL_SYS_VMS) 1951 struct timeb tb; 1952 ftime(&tb); 1953 t->tv_sec = (long)tb.time; 1954 t->tv_usec = (long)tb.millitm * 1000; 1955#else 1956 gettimeofday(t, NULL); 1957#endif 1958 } 1959 1960#endif 1961