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