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