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