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