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