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