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