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