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