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->gauth_chunks; 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->gauth_chunks; 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 = NULL; 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 if (authkey == NULL) 1400 { 1401 ret = -1; 1402 break; 1403 } 1404 memset(authkey, 0x00, sockopt_len); 1405 authkey->sca_keynumber = authkeyid.scact_keynumber + 1; 1406#ifndef __FreeBSD__ 1407 /* This field is missing in FreeBSD 8.2 and earlier, 1408 * and FreeBSD 8.3 and higher work without it. 1409 */ 1410 authkey->sca_keylength = 64; 1411#endif 1412 memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t)); 1413 1414 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len); 1415 OPENSSL_free(authkey); 1416 authkey = NULL; 1417 if (ret < 0) break; 1418 1419 /* Reset active key */ 1420 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, 1421 &authkeyid, sizeof(struct sctp_authkeyid)); 1422 if (ret < 0) break; 1423 1424 break; 1425 case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY: 1426 /* Returns 0 on success, -1 otherwise. */ 1427 1428 /* Get active key */ 1429 sockopt_len = sizeof(struct sctp_authkeyid); 1430 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len); 1431 if (ret < 0) break; 1432 1433 /* Set active key */ 1434 authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1; 1435 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, 1436 &authkeyid, sizeof(struct sctp_authkeyid)); 1437 if (ret < 0) break; 1438 1439 /* CCS has been sent, so remember that and fall through 1440 * to check if we need to deactivate an old key 1441 */ 1442 data->ccs_sent = 1; 1443 1444 case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD: 1445 /* Returns 0 on success, -1 otherwise. */ 1446 1447 /* Has this command really been called or is this just a fall-through? */ 1448 if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD) 1449 data->ccs_rcvd = 1; 1450 1451 /* CSS has been both, received and sent, so deactivate an old key */ 1452 if (data->ccs_rcvd == 1 && data->ccs_sent == 1) 1453 { 1454 /* Get active key */ 1455 sockopt_len = sizeof(struct sctp_authkeyid); 1456 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len); 1457 if (ret < 0) break; 1458 1459 /* Deactivate key or delete second last key if 1460 * SCTP_AUTHENTICATION_EVENT is not available. 1461 */ 1462 authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; 1463#ifdef SCTP_AUTH_DEACTIVATE_KEY 1464 sockopt_len = sizeof(struct sctp_authkeyid); 1465 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY, 1466 &authkeyid, sockopt_len); 1467 if (ret < 0) break; 1468#endif 1469#ifndef SCTP_AUTHENTICATION_EVENT 1470 if (authkeyid.scact_keynumber > 0) 1471 { 1472 authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; 1473 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, 1474 &authkeyid, sizeof(struct sctp_authkeyid)); 1475 if (ret < 0) break; 1476 } 1477#endif 1478 1479 data->ccs_rcvd = 0; 1480 data->ccs_sent = 0; 1481 } 1482 break; 1483 case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO: 1484 /* Returns the size of the copied struct. */ 1485 if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo)) 1486 num = sizeof(struct bio_dgram_sctp_sndinfo); 1487 1488 memcpy(ptr, &(data->sndinfo), num); 1489 ret = num; 1490 break; 1491 case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO: 1492 /* Returns the size of the copied struct. */ 1493 if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo)) 1494 num = sizeof(struct bio_dgram_sctp_sndinfo); 1495 1496 memcpy(&(data->sndinfo), ptr, num); 1497 break; 1498 case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO: 1499 /* Returns the size of the copied struct. */ 1500 if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo)) 1501 num = sizeof(struct bio_dgram_sctp_rcvinfo); 1502 1503 memcpy(ptr, &data->rcvinfo, num); 1504 1505 ret = num; 1506 break; 1507 case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO: 1508 /* Returns the size of the copied struct. */ 1509 if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo)) 1510 num = sizeof(struct bio_dgram_sctp_rcvinfo); 1511 1512 memcpy(&(data->rcvinfo), ptr, num); 1513 break; 1514 case BIO_CTRL_DGRAM_SCTP_GET_PRINFO: 1515 /* Returns the size of the copied struct. */ 1516 if (num > (long) sizeof(struct bio_dgram_sctp_prinfo)) 1517 num = sizeof(struct bio_dgram_sctp_prinfo); 1518 1519 memcpy(ptr, &(data->prinfo), num); 1520 ret = num; 1521 break; 1522 case BIO_CTRL_DGRAM_SCTP_SET_PRINFO: 1523 /* Returns the size of the copied struct. */ 1524 if (num > (long) sizeof(struct bio_dgram_sctp_prinfo)) 1525 num = sizeof(struct bio_dgram_sctp_prinfo); 1526 1527 memcpy(&(data->prinfo), ptr, num); 1528 break; 1529 case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN: 1530 /* Returns always 1. */ 1531 if (num > 0) 1532 data->save_shutdown = 1; 1533 else 1534 data->save_shutdown = 0; 1535 break; 1536 1537 default: 1538 /* Pass to default ctrl function to 1539 * process SCTP unspecific commands 1540 */ 1541 ret=dgram_ctrl(b, cmd, num, ptr); 1542 break; 1543 } 1544 return(ret); 1545 } 1546 1547int BIO_dgram_sctp_notification_cb(BIO *b, 1548 void (*handle_notifications)(BIO *bio, void *context, void *buf), 1549 void *context) 1550 { 1551 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; 1552 1553 if (handle_notifications != NULL) 1554 { 1555 data->handle_notifications = handle_notifications; 1556 data->notification_context = context; 1557 } 1558 else 1559 return -1; 1560 1561 return 0; 1562 } 1563 1564int BIO_dgram_sctp_wait_for_dry(BIO *b) 1565{ 1566 int is_dry = 0; 1567 int n, sockflags, ret; 1568 union sctp_notification snp; 1569 struct msghdr msg; 1570 struct iovec iov; 1571#ifdef SCTP_EVENT 1572 struct sctp_event event; 1573#else 1574 struct sctp_event_subscribe event; 1575 socklen_t eventsize; 1576#endif 1577 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 1578 1579 /* set sender dry event */ 1580#ifdef SCTP_EVENT 1581 memset(&event, 0, sizeof(struct sctp_event)); 1582 event.se_assoc_id = 0; 1583 event.se_type = SCTP_SENDER_DRY_EVENT; 1584 event.se_on = 1; 1585 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); 1586#else 1587 eventsize = sizeof(struct sctp_event_subscribe); 1588 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); 1589 if (ret < 0) 1590 return -1; 1591 1592 event.sctp_sender_dry_event = 1; 1593 1594 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 1595#endif 1596 if (ret < 0) 1597 return -1; 1598 1599 /* peek for notification */ 1600 memset(&snp, 0x00, sizeof(union sctp_notification)); 1601 iov.iov_base = (char *)&snp; 1602 iov.iov_len = sizeof(union sctp_notification); 1603 msg.msg_name = NULL; 1604 msg.msg_namelen = 0; 1605 msg.msg_iov = &iov; 1606 msg.msg_iovlen = 1; 1607 msg.msg_control = NULL; 1608 msg.msg_controllen = 0; 1609 msg.msg_flags = 0; 1610 1611 n = recvmsg(b->num, &msg, MSG_PEEK); 1612 if (n <= 0) 1613 { 1614 if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK)) 1615 return -1; 1616 else 1617 return 0; 1618 } 1619 1620 /* if we find a notification, process it and try again if necessary */ 1621 while (msg.msg_flags & MSG_NOTIFICATION) 1622 { 1623 memset(&snp, 0x00, sizeof(union sctp_notification)); 1624 iov.iov_base = (char *)&snp; 1625 iov.iov_len = sizeof(union sctp_notification); 1626 msg.msg_name = NULL; 1627 msg.msg_namelen = 0; 1628 msg.msg_iov = &iov; 1629 msg.msg_iovlen = 1; 1630 msg.msg_control = NULL; 1631 msg.msg_controllen = 0; 1632 msg.msg_flags = 0; 1633 1634 n = recvmsg(b->num, &msg, 0); 1635 if (n <= 0) 1636 { 1637 if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK)) 1638 return -1; 1639 else 1640 return is_dry; 1641 } 1642 1643 if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) 1644 { 1645 is_dry = 1; 1646 1647 /* disable sender dry event */ 1648#ifdef SCTP_EVENT 1649 memset(&event, 0, sizeof(struct sctp_event)); 1650 event.se_assoc_id = 0; 1651 event.se_type = SCTP_SENDER_DRY_EVENT; 1652 event.se_on = 0; 1653 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); 1654#else 1655 eventsize = (socklen_t) sizeof(struct sctp_event_subscribe); 1656 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); 1657 if (ret < 0) 1658 return -1; 1659 1660 event.sctp_sender_dry_event = 0; 1661 1662 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 1663#endif 1664 if (ret < 0) 1665 return -1; 1666 } 1667 1668#ifdef SCTP_AUTHENTICATION_EVENT 1669 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) 1670 dgram_sctp_handle_auth_free_key_event(b, &snp); 1671#endif 1672 1673 if (data->handle_notifications != NULL) 1674 data->handle_notifications(b, data->notification_context, (void*) &snp); 1675 1676 /* found notification, peek again */ 1677 memset(&snp, 0x00, sizeof(union sctp_notification)); 1678 iov.iov_base = (char *)&snp; 1679 iov.iov_len = sizeof(union sctp_notification); 1680 msg.msg_name = NULL; 1681 msg.msg_namelen = 0; 1682 msg.msg_iov = &iov; 1683 msg.msg_iovlen = 1; 1684 msg.msg_control = NULL; 1685 msg.msg_controllen = 0; 1686 msg.msg_flags = 0; 1687 1688 /* if we have seen the dry already, don't wait */ 1689 if (is_dry) 1690 { 1691 sockflags = fcntl(b->num, F_GETFL, 0); 1692 fcntl(b->num, F_SETFL, O_NONBLOCK); 1693 } 1694 1695 n = recvmsg(b->num, &msg, MSG_PEEK); 1696 1697 if (is_dry) 1698 { 1699 fcntl(b->num, F_SETFL, sockflags); 1700 } 1701 1702 if (n <= 0) 1703 { 1704 if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK)) 1705 return -1; 1706 else 1707 return is_dry; 1708 } 1709 } 1710 1711 /* read anything else */ 1712 return is_dry; 1713} 1714 1715int BIO_dgram_sctp_msg_waiting(BIO *b) 1716 { 1717 int n, sockflags; 1718 union sctp_notification snp; 1719 struct msghdr msg; 1720 struct iovec iov; 1721 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 1722 1723 /* Check if there are any messages waiting to be read */ 1724 do 1725 { 1726 memset(&snp, 0x00, sizeof(union sctp_notification)); 1727 iov.iov_base = (char *)&snp; 1728 iov.iov_len = sizeof(union sctp_notification); 1729 msg.msg_name = NULL; 1730 msg.msg_namelen = 0; 1731 msg.msg_iov = &iov; 1732 msg.msg_iovlen = 1; 1733 msg.msg_control = NULL; 1734 msg.msg_controllen = 0; 1735 msg.msg_flags = 0; 1736 1737 sockflags = fcntl(b->num, F_GETFL, 0); 1738 fcntl(b->num, F_SETFL, O_NONBLOCK); 1739 n = recvmsg(b->num, &msg, MSG_PEEK); 1740 fcntl(b->num, F_SETFL, sockflags); 1741 1742 /* if notification, process and try again */ 1743 if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) 1744 { 1745#ifdef SCTP_AUTHENTICATION_EVENT 1746 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) 1747 dgram_sctp_handle_auth_free_key_event(b, &snp); 1748#endif 1749 1750 memset(&snp, 0x00, sizeof(union sctp_notification)); 1751 iov.iov_base = (char *)&snp; 1752 iov.iov_len = sizeof(union sctp_notification); 1753 msg.msg_name = NULL; 1754 msg.msg_namelen = 0; 1755 msg.msg_iov = &iov; 1756 msg.msg_iovlen = 1; 1757 msg.msg_control = NULL; 1758 msg.msg_controllen = 0; 1759 msg.msg_flags = 0; 1760 n = recvmsg(b->num, &msg, 0); 1761 1762 if (data->handle_notifications != NULL) 1763 data->handle_notifications(b, data->notification_context, (void*) &snp); 1764 } 1765 1766 } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)); 1767 1768 /* Return 1 if there is a message to be read, return 0 otherwise. */ 1769 if (n > 0) 1770 return 1; 1771 else 1772 return 0; 1773 } 1774 1775static int dgram_sctp_puts(BIO *bp, const char *str) 1776 { 1777 int n,ret; 1778 1779 n=strlen(str); 1780 ret=dgram_sctp_write(bp,str,n); 1781 return(ret); 1782 } 1783#endif 1784 1785static int BIO_dgram_should_retry(int i) 1786 { 1787 int err; 1788 1789 if ((i == 0) || (i == -1)) 1790 { 1791 err=get_last_socket_error(); 1792 1793#if defined(OPENSSL_SYS_WINDOWS) 1794 /* If the socket return value (i) is -1 1795 * and err is unexpectedly 0 at this point, 1796 * the error code was overwritten by 1797 * another system call before this error 1798 * handling is called. 1799 */ 1800#endif 1801 1802 return(BIO_dgram_non_fatal_error(err)); 1803 } 1804 return(0); 1805 } 1806 1807int BIO_dgram_non_fatal_error(int err) 1808 { 1809 switch (err) 1810 { 1811#if defined(OPENSSL_SYS_WINDOWS) 1812# if defined(WSAEWOULDBLOCK) 1813 case WSAEWOULDBLOCK: 1814# endif 1815 1816# if 0 /* This appears to always be an error */ 1817# if defined(WSAENOTCONN) 1818 case WSAENOTCONN: 1819# endif 1820# endif 1821#endif 1822 1823#ifdef EWOULDBLOCK 1824# ifdef WSAEWOULDBLOCK 1825# if WSAEWOULDBLOCK != EWOULDBLOCK 1826 case EWOULDBLOCK: 1827# endif 1828# else 1829 case EWOULDBLOCK: 1830# endif 1831#endif 1832 1833#ifdef EINTR 1834 case EINTR: 1835#endif 1836 1837#ifdef EAGAIN 1838#if EWOULDBLOCK != EAGAIN 1839 case EAGAIN: 1840# endif 1841#endif 1842 1843#ifdef EPROTO 1844 case EPROTO: 1845#endif 1846 1847#ifdef EINPROGRESS 1848 case EINPROGRESS: 1849#endif 1850 1851#ifdef EALREADY 1852 case EALREADY: 1853#endif 1854 1855 return(1); 1856 /* break; */ 1857 default: 1858 break; 1859 } 1860 return(0); 1861 } 1862 1863static void get_current_time(struct timeval *t) 1864 { 1865#ifdef OPENSSL_SYS_WIN32 1866 struct _timeb tb; 1867 _ftime(&tb); 1868 t->tv_sec = (long)tb.time; 1869 t->tv_usec = (long)tb.millitm * 1000; 1870#elif defined(OPENSSL_SYS_VMS) 1871 struct timeb tb; 1872 ftime(&tb); 1873 t->tv_sec = (long)tb.time; 1874 t->tv_usec = (long)tb.millitm * 1000; 1875#else 1876 gettimeofday(t, NULL); 1877#endif 1878 } 1879 1880#endif 1881