Home | History | Annotate | Download | only in bio
      1 /* crypto/bio/bio_dgram.c */
      2 /*
      3  * DTLS implementation written by Nagendra Modadugu
      4  * (nagendra (at) cs.stanford.edu) for the OpenSSL project 2005.
      5  */
      6 /* ====================================================================
      7  * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  *
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  *
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in
     18  *    the documentation and/or other materials provided with the
     19  *    distribution.
     20  *
     21  * 3. All advertising materials mentioning features or use of this
     22  *    software must display the following acknowledgment:
     23  *    "This product includes software developed by the OpenSSL Project
     24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     25  *
     26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     27  *    endorse or promote products derived from this software without
     28  *    prior written permission. For written permission, please contact
     29  *    openssl-core (at) OpenSSL.org.
     30  *
     31  * 5. Products derived from this software may not be called "OpenSSL"
     32  *    nor may "OpenSSL" appear in their names without prior written
     33  *    permission of the OpenSSL Project.
     34  *
     35  * 6. Redistributions of any form whatsoever must retain the following
     36  *    acknowledgment:
     37  *    "This product includes software developed by the OpenSSL Project
     38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     39  *
     40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     51  * OF THE POSSIBILITY OF SUCH DAMAGE.
     52  * ====================================================================
     53  *
     54  * This product includes cryptographic software written by Eric Young
     55  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     56  * Hudson (tjh (at) cryptsoft.com).
     57  *
     58  */
     59 
     60 
     61 #include <stdio.h>
     62 #include <errno.h>
     63 #define USE_SOCKETS
     64 #include "cryptlib.h"
     65 
     66 #include <openssl/bio.h>
     67 #ifndef OPENSSL_NO_DGRAM
     68 
     69 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
     70 #include <sys/timeb.h>
     71 #endif
     72 
     73 #ifndef OPENSSL_NO_SCTP
     74 #include <netinet/sctp.h>
     75 #include <fcntl.h>
     76 #define OPENSSL_SCTP_DATA_CHUNK_TYPE            0x00
     77 #define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
     78 #endif
     79 
     80 #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 
    100 static int dgram_write(BIO *h, const char *buf, int num);
    101 static int dgram_read(BIO *h, char *buf, int size);
    102 static int dgram_puts(BIO *h, const char *str);
    103 static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
    104 static int dgram_new(BIO *h);
    105 static int dgram_free(BIO *data);
    106 static int dgram_clear(BIO *bio);
    107 
    108 #ifndef OPENSSL_NO_SCTP
    109 static int dgram_sctp_write(BIO *h, const char *buf, int num);
    110 static int dgram_sctp_read(BIO *h, char *buf, int size);
    111 static int dgram_sctp_puts(BIO *h, const char *str);
    112 static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
    113 static int dgram_sctp_new(BIO *h);
    114 static int dgram_sctp_free(BIO *data);
    115 #ifdef SCTP_AUTHENTICATION_EVENT
    116 static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp);
    117 #endif
    118 #endif
    119 
    120 static int BIO_dgram_should_retry(int s);
    121 
    122 static void get_current_time(struct timeval *t);
    123 
    124 static 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
    139 static 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 
    154 typedef 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
    171 typedef struct bio_dgram_sctp_save_message_st
    172 	{
    173         BIO *bio;
    174         char *data;
    175         int length;
    176 	} bio_dgram_sctp_save_message;
    177 
    178 typedef 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 
    204 BIO_METHOD *BIO_s_datagram(void)
    205 	{
    206 	return(&methods_dgramp);
    207 	}
    208 
    209 BIO *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 
    219 static 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 
    235 static 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 
    249 static 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 
    264 static 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 
    339 static 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 
    362 static 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 
    414 static 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 
    457 static 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 
    857 static 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
    867 BIO_METHOD *BIO_s_datagram_sctp(void)
    868 	{
    869 	return(&methods_dgramp_sctp);
    870 	}
    871 
    872 BIO *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 
    952 int BIO_dgram_is_sctp(BIO *bio)
    953 	{
    954 	return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
    955 	}
    956 
    957 static 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 
    976 static 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) OPENSSL_free(data);
    986 
    987 	return(1);
    988 	}
    989 
    990 #ifdef SCTP_AUTHENTICATION_EVENT
    991 void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
    992 	{
    993 	int ret;
    994 	struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event;
    995 
    996 	if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY)
    997 		{
    998 		struct sctp_authkeyid authkeyid;
    999 
   1000 		/* delete key */
   1001 		authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
   1002 		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
   1003 		      &authkeyid, sizeof(struct sctp_authkeyid));
   1004 		}
   1005 	}
   1006 #endif
   1007 
   1008 static int dgram_sctp_read(BIO *b, char *out, int outl)
   1009 	{
   1010 	int ret = 0, n = 0, i, optval;
   1011 	socklen_t optlen;
   1012 	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
   1013 	union sctp_notification *snp;
   1014 	struct msghdr msg;
   1015 	struct iovec iov;
   1016 	struct cmsghdr *cmsg;
   1017 	char cmsgbuf[512];
   1018 
   1019 	if (out != NULL)
   1020 		{
   1021 		clear_socket_error();
   1022 
   1023 		do
   1024 			{
   1025 			memset(&data->rcvinfo, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo));
   1026 			iov.iov_base = out;
   1027 			iov.iov_len = outl;
   1028 			msg.msg_name = NULL;
   1029 			msg.msg_namelen = 0;
   1030 			msg.msg_iov = &iov;
   1031 			msg.msg_iovlen = 1;
   1032 			msg.msg_control = cmsgbuf;
   1033 			msg.msg_controllen = 512;
   1034 			msg.msg_flags = 0;
   1035 			n = recvmsg(b->num, &msg, 0);
   1036 
   1037 			if (msg.msg_controllen > 0)
   1038 				{
   1039 				for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
   1040 					{
   1041 					if (cmsg->cmsg_level != IPPROTO_SCTP)
   1042 						continue;
   1043 #ifdef SCTP_RCVINFO
   1044 					if (cmsg->cmsg_type == SCTP_RCVINFO)
   1045 						{
   1046 						struct sctp_rcvinfo *rcvinfo;
   1047 
   1048 						rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
   1049 						data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
   1050 						data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
   1051 						data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
   1052 						data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
   1053 						data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
   1054 						data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
   1055 						data->rcvinfo.rcv_context = rcvinfo->rcv_context;
   1056 						}
   1057 #endif
   1058 #ifdef SCTP_SNDRCV
   1059 					if (cmsg->cmsg_type == SCTP_SNDRCV)
   1060 						{
   1061 						struct sctp_sndrcvinfo *sndrcvinfo;
   1062 
   1063 						sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
   1064 						data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
   1065 						data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
   1066 						data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
   1067 						data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
   1068 						data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
   1069 						data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
   1070 						data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
   1071 						}
   1072 #endif
   1073 					}
   1074 				}
   1075 
   1076 			if (n <= 0)
   1077 				{
   1078 				if (n < 0)
   1079 					ret = n;
   1080 				break;
   1081 				}
   1082 
   1083 			if (msg.msg_flags & MSG_NOTIFICATION)
   1084 				{
   1085 				snp = (union sctp_notification*) out;
   1086 				if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
   1087 					{
   1088 #ifdef SCTP_EVENT
   1089 					struct sctp_event event;
   1090 #else
   1091 					struct sctp_event_subscribe event;
   1092 					socklen_t eventsize;
   1093 #endif
   1094 					/* If a message has been delayed until the socket
   1095 					 * is dry, it can be sent now.
   1096 					 */
   1097 					if (data->saved_message.length > 0)
   1098 						{
   1099 						dgram_sctp_write(data->saved_message.bio, data->saved_message.data,
   1100 						                 data->saved_message.length);
   1101 						OPENSSL_free(data->saved_message.data);
   1102 						data->saved_message.length = 0;
   1103 						}
   1104 
   1105 					/* disable sender dry event */
   1106 #ifdef SCTP_EVENT
   1107 					memset(&event, 0, sizeof(struct sctp_event));
   1108 					event.se_assoc_id = 0;
   1109 					event.se_type = SCTP_SENDER_DRY_EVENT;
   1110 					event.se_on = 0;
   1111 					i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
   1112 					OPENSSL_assert(i >= 0);
   1113 #else
   1114 					eventsize = sizeof(struct sctp_event_subscribe);
   1115 					i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
   1116 					OPENSSL_assert(i >= 0);
   1117 
   1118 					event.sctp_sender_dry_event = 0;
   1119 
   1120 					i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
   1121 					OPENSSL_assert(i >= 0);
   1122 #endif
   1123 					}
   1124 
   1125 #ifdef SCTP_AUTHENTICATION_EVENT
   1126 				if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
   1127 					dgram_sctp_handle_auth_free_key_event(b, snp);
   1128 #endif
   1129 
   1130 				if (data->handle_notifications != NULL)
   1131 					data->handle_notifications(b, data->notification_context, (void*) out);
   1132 
   1133 				memset(out, 0, outl);
   1134 				}
   1135 			else
   1136 				ret += n;
   1137 			}
   1138 		while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl));
   1139 
   1140 		if (ret > 0 && !(msg.msg_flags & MSG_EOR))
   1141 			{
   1142 			/* Partial message read, this should never happen! */
   1143 
   1144 			/* The buffer was too small, this means the peer sent
   1145 			 * a message that was larger than allowed. */
   1146 			if (ret == outl)
   1147 				return -1;
   1148 
   1149 			/* Test if socket buffer can handle max record
   1150 			 * size (2^14 + 2048 + 13)
   1151 			 */
   1152 			optlen = (socklen_t) sizeof(int);
   1153 			ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
   1154 			OPENSSL_assert(ret >= 0);
   1155 			OPENSSL_assert(optval >= 18445);
   1156 
   1157 			/* Test if SCTP doesn't partially deliver below
   1158 			 * max record size (2^14 + 2048 + 13)
   1159 			 */
   1160 			optlen = (socklen_t) sizeof(int);
   1161 			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
   1162 			                 &optval, &optlen);
   1163 			OPENSSL_assert(ret >= 0);
   1164 			OPENSSL_assert(optval >= 18445);
   1165 
   1166 			/* Partially delivered notification??? Probably a bug.... */
   1167 			OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
   1168 
   1169 			/* Everything seems ok till now, so it's most likely
   1170 			 * a message dropped by PR-SCTP.
   1171 			 */
   1172 			memset(out, 0, outl);
   1173 			BIO_set_retry_read(b);
   1174 			return -1;
   1175 			}
   1176 
   1177 		BIO_clear_retry_flags(b);
   1178 		if (ret < 0)
   1179 			{
   1180 			if (BIO_dgram_should_retry(ret))
   1181 				{
   1182 				BIO_set_retry_read(b);
   1183 				data->_errno = get_last_socket_error();
   1184 				}
   1185 			}
   1186 
   1187 		/* Test if peer uses SCTP-AUTH before continuing */
   1188 		if (!data->peer_auth_tested)
   1189 			{
   1190 			int ii, auth_data = 0, auth_forward = 0;
   1191 			unsigned char *p;
   1192 			struct sctp_authchunks *authchunks;
   1193 
   1194 			optlen = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
   1195 			authchunks = OPENSSL_malloc(optlen);
   1196 			memset(authchunks, 0, sizeof(optlen));
   1197 			ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen);
   1198 			OPENSSL_assert(ii >= 0);
   1199 
   1200 			for (p = (unsigned char*) authchunks->gauth_chunks;
   1201 				 p < (unsigned char*) authchunks + optlen;
   1202 				 p += sizeof(uint8_t))
   1203 				{
   1204 				if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1;
   1205 				if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1;
   1206 				}
   1207 
   1208 			OPENSSL_free(authchunks);
   1209 
   1210 			if (!auth_data || !auth_forward)
   1211 				{
   1212 				BIOerr(BIO_F_DGRAM_SCTP_READ,BIO_R_CONNECT_ERROR);
   1213 				return -1;
   1214 				}
   1215 
   1216 			data->peer_auth_tested = 1;
   1217 			}
   1218 		}
   1219 	return(ret);
   1220 	}
   1221 
   1222 static int dgram_sctp_write(BIO *b, const char *in, int inl)
   1223 	{
   1224 	int ret;
   1225 	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
   1226 	struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
   1227 	struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
   1228 	struct bio_dgram_sctp_sndinfo handshake_sinfo;
   1229 	struct iovec iov[1];
   1230 	struct msghdr msg;
   1231 	struct cmsghdr *cmsg;
   1232 #if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
   1233 	char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + CMSG_SPACE(sizeof(struct sctp_prinfo))];
   1234 	struct sctp_sndinfo *sndinfo;
   1235 	struct sctp_prinfo *prinfo;
   1236 #else
   1237 	char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
   1238 	struct sctp_sndrcvinfo *sndrcvinfo;
   1239 #endif
   1240 
   1241 	clear_socket_error();
   1242 
   1243 	/* If we're send anything else than application data,
   1244 	 * disable all user parameters and flags.
   1245 	 */
   1246 	if (in[0] != 23) {
   1247 		memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo));
   1248 #ifdef SCTP_SACK_IMMEDIATELY
   1249 		handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
   1250 #endif
   1251 		sinfo = &handshake_sinfo;
   1252 	}
   1253 
   1254 	/* If we have to send a shutdown alert message and the
   1255 	 * socket is not dry yet, we have to save it and send it
   1256 	 * as soon as the socket gets dry.
   1257 	 */
   1258 	if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b))
   1259 	{
   1260 		data->saved_message.bio = b;
   1261 		data->saved_message.length = inl;
   1262 		data->saved_message.data = OPENSSL_malloc(inl);
   1263 		memcpy(data->saved_message.data, in, inl);
   1264 		return inl;
   1265 	}
   1266 
   1267 	iov[0].iov_base = (char *)in;
   1268 	iov[0].iov_len = inl;
   1269 	msg.msg_name = NULL;
   1270 	msg.msg_namelen = 0;
   1271 	msg.msg_iov = iov;
   1272 	msg.msg_iovlen = 1;
   1273 	msg.msg_control = (caddr_t)cmsgbuf;
   1274 	msg.msg_controllen = 0;
   1275 	msg.msg_flags = 0;
   1276 #if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
   1277 	cmsg = (struct cmsghdr *)cmsgbuf;
   1278 	cmsg->cmsg_level = IPPROTO_SCTP;
   1279 	cmsg->cmsg_type = SCTP_SNDINFO;
   1280 	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
   1281 	sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
   1282 	memset(sndinfo, 0, sizeof(struct sctp_sndinfo));
   1283 	sndinfo->snd_sid = sinfo->snd_sid;
   1284 	sndinfo->snd_flags = sinfo->snd_flags;
   1285 	sndinfo->snd_ppid = sinfo->snd_ppid;
   1286 	sndinfo->snd_context = sinfo->snd_context;
   1287 	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
   1288 
   1289 	cmsg = (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
   1290 	cmsg->cmsg_level = IPPROTO_SCTP;
   1291 	cmsg->cmsg_type = SCTP_PRINFO;
   1292 	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
   1293 	prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
   1294 	memset(prinfo, 0, sizeof(struct sctp_prinfo));
   1295 	prinfo->pr_policy = pinfo->pr_policy;
   1296 	prinfo->pr_value = pinfo->pr_value;
   1297 	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
   1298 #else
   1299 	cmsg = (struct cmsghdr *)cmsgbuf;
   1300 	cmsg->cmsg_level = IPPROTO_SCTP;
   1301 	cmsg->cmsg_type = SCTP_SNDRCV;
   1302 	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
   1303 	sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
   1304 	memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
   1305 	sndrcvinfo->sinfo_stream = sinfo->snd_sid;
   1306 	sndrcvinfo->sinfo_flags = sinfo->snd_flags;
   1307 #ifdef __FreeBSD__
   1308 	sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
   1309 #endif
   1310 	sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
   1311 	sndrcvinfo->sinfo_context = sinfo->snd_context;
   1312 	sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
   1313 	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
   1314 #endif
   1315 
   1316 	ret = sendmsg(b->num, &msg, 0);
   1317 
   1318 	BIO_clear_retry_flags(b);
   1319 	if (ret <= 0)
   1320 		{
   1321 		if (BIO_dgram_should_retry(ret))
   1322 			{
   1323 			BIO_set_retry_write(b);
   1324 			data->_errno = get_last_socket_error();
   1325 			}
   1326 		}
   1327 	return(ret);
   1328 	}
   1329 
   1330 static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
   1331 	{
   1332 	long ret=1;
   1333 	bio_dgram_sctp_data *data = NULL;
   1334 	socklen_t sockopt_len = 0;
   1335 	struct sctp_authkeyid authkeyid;
   1336 	struct sctp_authkey *authkey = NULL;
   1337 
   1338 	data = (bio_dgram_sctp_data *)b->ptr;
   1339 
   1340 	switch (cmd)
   1341 		{
   1342 	case BIO_CTRL_DGRAM_QUERY_MTU:
   1343 		/* Set to maximum (2^14)
   1344 		 * and ignore user input to enable transport
   1345 		 * protocol fragmentation.
   1346 		 * Returns always 2^14.
   1347 		 */
   1348 		data->mtu = 16384;
   1349 		ret = data->mtu;
   1350 		break;
   1351 	case BIO_CTRL_DGRAM_SET_MTU:
   1352 		/* Set to maximum (2^14)
   1353 		 * and ignore input to enable transport
   1354 		 * protocol fragmentation.
   1355 		 * Returns always 2^14.
   1356 		 */
   1357 		data->mtu = 16384;
   1358 		ret = data->mtu;
   1359 		break;
   1360 	case BIO_CTRL_DGRAM_SET_CONNECTED:
   1361 	case BIO_CTRL_DGRAM_CONNECT:
   1362 		/* Returns always -1. */
   1363 		ret = -1;
   1364 		break;
   1365 	case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
   1366 		/* SCTP doesn't need the DTLS timer
   1367 		 * Returns always 1.
   1368 		 */
   1369 		break;
   1370 	case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
   1371 		if (num > 0)
   1372 			data->in_handshake = 1;
   1373 		else
   1374 			data->in_handshake = 0;
   1375 
   1376 		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY, &data->in_handshake, sizeof(int));
   1377 		break;
   1378 	case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
   1379 		/* New shared key for SCTP AUTH.
   1380 		 * Returns 0 on success, -1 otherwise.
   1381 		 */
   1382 
   1383 		/* Get active key */
   1384 		sockopt_len = sizeof(struct sctp_authkeyid);
   1385 		ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
   1386 		if (ret < 0) break;
   1387 
   1388 		/* Add new key */
   1389 		sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
   1390 		authkey = OPENSSL_malloc(sockopt_len);
   1391 		if (authkey == NULL)
   1392 			{
   1393 			ret = -1;
   1394 			break;
   1395 			}
   1396 		memset(authkey, 0x00, sockopt_len);
   1397 		authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
   1398 #ifndef __FreeBSD__
   1399 		/* This field is missing in FreeBSD 8.2 and earlier,
   1400 		 * and FreeBSD 8.3 and higher work without it.
   1401 		 */
   1402 		authkey->sca_keylength = 64;
   1403 #endif
   1404 		memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
   1405 
   1406 		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len);
   1407 		OPENSSL_free(authkey);
   1408 		authkey = NULL;
   1409 		if (ret < 0) break;
   1410 
   1411 		/* Reset active key */
   1412 		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
   1413 		      &authkeyid, sizeof(struct sctp_authkeyid));
   1414 		if (ret < 0) break;
   1415 
   1416 		break;
   1417 	case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
   1418 		/* Returns 0 on success, -1 otherwise. */
   1419 
   1420 		/* Get active key */
   1421 		sockopt_len = sizeof(struct sctp_authkeyid);
   1422 		ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
   1423 		if (ret < 0) break;
   1424 
   1425 		/* Set active key */
   1426 		authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
   1427 		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
   1428 		      &authkeyid, sizeof(struct sctp_authkeyid));
   1429 		if (ret < 0) break;
   1430 
   1431 		/* CCS has been sent, so remember that and fall through
   1432 		 * to check if we need to deactivate an old key
   1433 		 */
   1434 		data->ccs_sent = 1;
   1435 
   1436 	case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
   1437 		/* Returns 0 on success, -1 otherwise. */
   1438 
   1439 		/* Has this command really been called or is this just a fall-through? */
   1440 		if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
   1441 			data->ccs_rcvd = 1;
   1442 
   1443 		/* CSS has been both, received and sent, so deactivate an old key */
   1444 		if (data->ccs_rcvd == 1 && data->ccs_sent == 1)
   1445 			{
   1446 			/* Get active key */
   1447 			sockopt_len = sizeof(struct sctp_authkeyid);
   1448 			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
   1449 			if (ret < 0) break;
   1450 
   1451 			/* Deactivate key or delete second last key if
   1452 			 * SCTP_AUTHENTICATION_EVENT is not available.
   1453 			 */
   1454 			authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
   1455 #ifdef SCTP_AUTH_DEACTIVATE_KEY
   1456 			sockopt_len = sizeof(struct sctp_authkeyid);
   1457 			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
   1458 			      &authkeyid, sockopt_len);
   1459 			if (ret < 0) break;
   1460 #endif
   1461 #ifndef SCTP_AUTHENTICATION_EVENT
   1462 			if (authkeyid.scact_keynumber > 0)
   1463 				{
   1464 				authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
   1465 				ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
   1466 					  &authkeyid, sizeof(struct sctp_authkeyid));
   1467 				if (ret < 0) break;
   1468 				}
   1469 #endif
   1470 
   1471 			data->ccs_rcvd = 0;
   1472 			data->ccs_sent = 0;
   1473 			}
   1474 		break;
   1475 	case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
   1476 		/* Returns the size of the copied struct. */
   1477 		if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo))
   1478 			num = sizeof(struct bio_dgram_sctp_sndinfo);
   1479 
   1480 		memcpy(ptr, &(data->sndinfo), num);
   1481 		ret = num;
   1482 		break;
   1483 	case BIO_CTRL_DGRAM_SCTP_SET_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(&(data->sndinfo), ptr, num);
   1489 		break;
   1490 	case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
   1491 		/* Returns the size of the copied struct. */
   1492 		if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
   1493 			num = sizeof(struct bio_dgram_sctp_rcvinfo);
   1494 
   1495 		memcpy(ptr, &data->rcvinfo, num);
   1496 
   1497 		ret = num;
   1498 		break;
   1499 	case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
   1500 		/* Returns the size of the copied struct. */
   1501 		if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
   1502 			num = sizeof(struct bio_dgram_sctp_rcvinfo);
   1503 
   1504 		memcpy(&(data->rcvinfo), ptr, num);
   1505 		break;
   1506 	case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
   1507 		/* Returns the size of the copied struct. */
   1508 		if (num > (long) sizeof(struct bio_dgram_sctp_prinfo))
   1509 			num = sizeof(struct bio_dgram_sctp_prinfo);
   1510 
   1511 		memcpy(ptr, &(data->prinfo), num);
   1512 		ret = num;
   1513 		break;
   1514 	case BIO_CTRL_DGRAM_SCTP_SET_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(&(data->prinfo), ptr, num);
   1520 		break;
   1521 	case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
   1522 		/* Returns always 1. */
   1523 		if (num > 0)
   1524 			data->save_shutdown = 1;
   1525 		else
   1526 			data->save_shutdown = 0;
   1527 		break;
   1528 
   1529 	default:
   1530 		/* Pass to default ctrl function to
   1531 		 * process SCTP unspecific commands
   1532 		 */
   1533 		ret=dgram_ctrl(b, cmd, num, ptr);
   1534 		break;
   1535 		}
   1536 	return(ret);
   1537 	}
   1538 
   1539 int BIO_dgram_sctp_notification_cb(BIO *b,
   1540                                    void (*handle_notifications)(BIO *bio, void *context, void *buf),
   1541                                    void *context)
   1542 	{
   1543 	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
   1544 
   1545 	if (handle_notifications != NULL)
   1546 		{
   1547 		data->handle_notifications = handle_notifications;
   1548 		data->notification_context = context;
   1549 		}
   1550 	else
   1551 		return -1;
   1552 
   1553 	return 0;
   1554 	}
   1555 
   1556 int BIO_dgram_sctp_wait_for_dry(BIO *b)
   1557 {
   1558 	int is_dry = 0;
   1559 	int n, sockflags, ret;
   1560 	union sctp_notification snp;
   1561 	struct msghdr msg;
   1562 	struct iovec iov;
   1563 #ifdef SCTP_EVENT
   1564 	struct sctp_event event;
   1565 #else
   1566 	struct sctp_event_subscribe event;
   1567 	socklen_t eventsize;
   1568 #endif
   1569 	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
   1570 
   1571 	/* set sender dry event */
   1572 #ifdef SCTP_EVENT
   1573 	memset(&event, 0, sizeof(struct sctp_event));
   1574 	event.se_assoc_id = 0;
   1575 	event.se_type = SCTP_SENDER_DRY_EVENT;
   1576 	event.se_on = 1;
   1577 	ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
   1578 #else
   1579 	eventsize = sizeof(struct sctp_event_subscribe);
   1580 	ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
   1581 	if (ret < 0)
   1582 		return -1;
   1583 
   1584 	event.sctp_sender_dry_event = 1;
   1585 
   1586 	ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
   1587 #endif
   1588 	if (ret < 0)
   1589 		return -1;
   1590 
   1591 	/* peek for notification */
   1592 	memset(&snp, 0x00, sizeof(union sctp_notification));
   1593 	iov.iov_base = (char *)&snp;
   1594 	iov.iov_len = sizeof(union sctp_notification);
   1595 	msg.msg_name = NULL;
   1596 	msg.msg_namelen = 0;
   1597 	msg.msg_iov = &iov;
   1598 	msg.msg_iovlen = 1;
   1599 	msg.msg_control = NULL;
   1600 	msg.msg_controllen = 0;
   1601 	msg.msg_flags = 0;
   1602 
   1603 	n = recvmsg(b->num, &msg, MSG_PEEK);
   1604 	if (n <= 0)
   1605 		{
   1606 		if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
   1607 			return -1;
   1608 		else
   1609 			return 0;
   1610 		}
   1611 
   1612 	/* if we find a notification, process it and try again if necessary */
   1613 	while (msg.msg_flags & MSG_NOTIFICATION)
   1614 		{
   1615 		memset(&snp, 0x00, sizeof(union sctp_notification));
   1616 		iov.iov_base = (char *)&snp;
   1617 		iov.iov_len = sizeof(union sctp_notification);
   1618 		msg.msg_name = NULL;
   1619 		msg.msg_namelen = 0;
   1620 		msg.msg_iov = &iov;
   1621 		msg.msg_iovlen = 1;
   1622 		msg.msg_control = NULL;
   1623 		msg.msg_controllen = 0;
   1624 		msg.msg_flags = 0;
   1625 
   1626 		n = recvmsg(b->num, &msg, 0);
   1627 		if (n <= 0)
   1628 			{
   1629 			if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
   1630 				return -1;
   1631 			else
   1632 				return is_dry;
   1633 			}
   1634 
   1635 		if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
   1636 			{
   1637 			is_dry = 1;
   1638 
   1639 			/* disable sender dry event */
   1640 #ifdef SCTP_EVENT
   1641 			memset(&event, 0, sizeof(struct sctp_event));
   1642 			event.se_assoc_id = 0;
   1643 			event.se_type = SCTP_SENDER_DRY_EVENT;
   1644 			event.se_on = 0;
   1645 			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
   1646 #else
   1647 			eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
   1648 			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
   1649 			if (ret < 0)
   1650 				return -1;
   1651 
   1652 			event.sctp_sender_dry_event = 0;
   1653 
   1654 			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
   1655 #endif
   1656 			if (ret < 0)
   1657 				return -1;
   1658 			}
   1659 
   1660 #ifdef SCTP_AUTHENTICATION_EVENT
   1661 		if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
   1662 			dgram_sctp_handle_auth_free_key_event(b, &snp);
   1663 #endif
   1664 
   1665 		if (data->handle_notifications != NULL)
   1666 			data->handle_notifications(b, data->notification_context, (void*) &snp);
   1667 
   1668 		/* found notification, peek again */
   1669 		memset(&snp, 0x00, sizeof(union sctp_notification));
   1670 		iov.iov_base = (char *)&snp;
   1671 		iov.iov_len = sizeof(union sctp_notification);
   1672 		msg.msg_name = NULL;
   1673 		msg.msg_namelen = 0;
   1674 		msg.msg_iov = &iov;
   1675 		msg.msg_iovlen = 1;
   1676 		msg.msg_control = NULL;
   1677 		msg.msg_controllen = 0;
   1678 		msg.msg_flags = 0;
   1679 
   1680 		/* if we have seen the dry already, don't wait */
   1681 		if (is_dry)
   1682 			{
   1683 			sockflags = fcntl(b->num, F_GETFL, 0);
   1684 			fcntl(b->num, F_SETFL, O_NONBLOCK);
   1685 			}
   1686 
   1687 		n = recvmsg(b->num, &msg, MSG_PEEK);
   1688 
   1689 		if (is_dry)
   1690 			{
   1691 			fcntl(b->num, F_SETFL, sockflags);
   1692 			}
   1693 
   1694 		if (n <= 0)
   1695 			{
   1696 			if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
   1697 				return -1;
   1698 			else
   1699 				return is_dry;
   1700 			}
   1701 		}
   1702 
   1703 	/* read anything else */
   1704 	return is_dry;
   1705 }
   1706 
   1707 int BIO_dgram_sctp_msg_waiting(BIO *b)
   1708 	{
   1709 	int n, sockflags;
   1710 	union sctp_notification snp;
   1711 	struct msghdr msg;
   1712 	struct iovec iov;
   1713 	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
   1714 
   1715 	/* Check if there are any messages waiting to be read */
   1716 	do
   1717 		{
   1718 		memset(&snp, 0x00, sizeof(union sctp_notification));
   1719 		iov.iov_base = (char *)&snp;
   1720 		iov.iov_len = sizeof(union sctp_notification);
   1721 		msg.msg_name = NULL;
   1722 		msg.msg_namelen = 0;
   1723 		msg.msg_iov = &iov;
   1724 		msg.msg_iovlen = 1;
   1725 		msg.msg_control = NULL;
   1726 		msg.msg_controllen = 0;
   1727 		msg.msg_flags = 0;
   1728 
   1729 		sockflags = fcntl(b->num, F_GETFL, 0);
   1730 		fcntl(b->num, F_SETFL, O_NONBLOCK);
   1731 		n = recvmsg(b->num, &msg, MSG_PEEK);
   1732 		fcntl(b->num, F_SETFL, sockflags);
   1733 
   1734 		/* if notification, process and try again */
   1735 		if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION))
   1736 			{
   1737 #ifdef SCTP_AUTHENTICATION_EVENT
   1738 			if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
   1739 				dgram_sctp_handle_auth_free_key_event(b, &snp);
   1740 #endif
   1741 
   1742 			memset(&snp, 0x00, sizeof(union sctp_notification));
   1743 			iov.iov_base = (char *)&snp;
   1744 			iov.iov_len = sizeof(union sctp_notification);
   1745 			msg.msg_name = NULL;
   1746 			msg.msg_namelen = 0;
   1747 			msg.msg_iov = &iov;
   1748 			msg.msg_iovlen = 1;
   1749 			msg.msg_control = NULL;
   1750 			msg.msg_controllen = 0;
   1751 			msg.msg_flags = 0;
   1752 			n = recvmsg(b->num, &msg, 0);
   1753 
   1754 			if (data->handle_notifications != NULL)
   1755 				data->handle_notifications(b, data->notification_context, (void*) &snp);
   1756 			}
   1757 
   1758 		} while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
   1759 
   1760 	/* Return 1 if there is a message to be read, return 0 otherwise. */
   1761 	if (n > 0)
   1762 		return 1;
   1763 	else
   1764 		return 0;
   1765 	}
   1766 
   1767 static int dgram_sctp_puts(BIO *bp, const char *str)
   1768 	{
   1769 	int n,ret;
   1770 
   1771 	n=strlen(str);
   1772 	ret=dgram_sctp_write(bp,str,n);
   1773 	return(ret);
   1774 	}
   1775 #endif
   1776 
   1777 static int BIO_dgram_should_retry(int i)
   1778 	{
   1779 	int err;
   1780 
   1781 	if ((i == 0) || (i == -1))
   1782 		{
   1783 		err=get_last_socket_error();
   1784 
   1785 #if defined(OPENSSL_SYS_WINDOWS)
   1786 	/* If the socket return value (i) is -1
   1787 	 * and err is unexpectedly 0 at this point,
   1788 	 * the error code was overwritten by
   1789 	 * another system call before this error
   1790 	 * handling is called.
   1791 	 */
   1792 #endif
   1793 
   1794 		return(BIO_dgram_non_fatal_error(err));
   1795 		}
   1796 	return(0);
   1797 	}
   1798 
   1799 int BIO_dgram_non_fatal_error(int err)
   1800 	{
   1801 	switch (err)
   1802 		{
   1803 #if defined(OPENSSL_SYS_WINDOWS)
   1804 # if defined(WSAEWOULDBLOCK)
   1805 	case WSAEWOULDBLOCK:
   1806 # endif
   1807 
   1808 # if 0 /* This appears to always be an error */
   1809 #  if defined(WSAENOTCONN)
   1810 	case WSAENOTCONN:
   1811 #  endif
   1812 # endif
   1813 #endif
   1814 
   1815 #ifdef EWOULDBLOCK
   1816 # ifdef WSAEWOULDBLOCK
   1817 #  if WSAEWOULDBLOCK != EWOULDBLOCK
   1818 	case EWOULDBLOCK:
   1819 #  endif
   1820 # else
   1821 	case EWOULDBLOCK:
   1822 # endif
   1823 #endif
   1824 
   1825 #ifdef EINTR
   1826 	case EINTR:
   1827 #endif
   1828 
   1829 #ifdef EAGAIN
   1830 #if EWOULDBLOCK != EAGAIN
   1831 	case EAGAIN:
   1832 # endif
   1833 #endif
   1834 
   1835 #ifdef EPROTO
   1836 	case EPROTO:
   1837 #endif
   1838 
   1839 #ifdef EINPROGRESS
   1840 	case EINPROGRESS:
   1841 #endif
   1842 
   1843 #ifdef EALREADY
   1844 	case EALREADY:
   1845 #endif
   1846 
   1847 		return(1);
   1848 		/* break; */
   1849 	default:
   1850 		break;
   1851 		}
   1852 	return(0);
   1853 	}
   1854 
   1855 static void get_current_time(struct timeval *t)
   1856 	{
   1857 #ifdef OPENSSL_SYS_WIN32
   1858 	struct _timeb tb;
   1859 	_ftime(&tb);
   1860 	t->tv_sec = (long)tb.time;
   1861 	t->tv_usec = (long)tb.millitm * 1000;
   1862 #elif defined(OPENSSL_SYS_VMS)
   1863 	struct timeb tb;
   1864 	ftime(&tb);
   1865 	t->tv_sec = (long)tb.time;
   1866 	t->tv_usec = (long)tb.millitm * 1000;
   1867 #else
   1868 	gettimeofday(t, NULL);
   1869 #endif
   1870 	}
   1871 
   1872 #endif
   1873