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