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) OPENSSL_free(data);
986
987	return(1);
988	}
989
990#ifdef SCTP_AUTHENTICATION_EVENT
991void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
992	{
993	int ret;
994	struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event;
995
996	if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY)
997		{
998		struct sctp_authkeyid authkeyid;
999
1000		/* delete key */
1001		authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
1002		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
1003		      &authkeyid, sizeof(struct sctp_authkeyid));
1004		}
1005	}
1006#endif
1007
1008static int dgram_sctp_read(BIO *b, char *out, int outl)
1009	{
1010	int ret = 0, n = 0, i, optval;
1011	socklen_t optlen;
1012	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
1013	union sctp_notification *snp;
1014	struct msghdr msg;
1015	struct iovec iov;
1016	struct cmsghdr *cmsg;
1017	char cmsgbuf[512];
1018
1019	if (out != NULL)
1020		{
1021		clear_socket_error();
1022
1023		do
1024			{
1025			memset(&data->rcvinfo, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo));
1026			iov.iov_base = out;
1027			iov.iov_len = outl;
1028			msg.msg_name = NULL;
1029			msg.msg_namelen = 0;
1030			msg.msg_iov = &iov;
1031			msg.msg_iovlen = 1;
1032			msg.msg_control = cmsgbuf;
1033			msg.msg_controllen = 512;
1034			msg.msg_flags = 0;
1035			n = recvmsg(b->num, &msg, 0);
1036
1037			if (msg.msg_controllen > 0)
1038				{
1039				for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
1040					{
1041					if (cmsg->cmsg_level != IPPROTO_SCTP)
1042						continue;
1043#ifdef SCTP_RCVINFO
1044					if (cmsg->cmsg_type == SCTP_RCVINFO)
1045						{
1046						struct sctp_rcvinfo *rcvinfo;
1047
1048						rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
1049						data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
1050						data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
1051						data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
1052						data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
1053						data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
1054						data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
1055						data->rcvinfo.rcv_context = rcvinfo->rcv_context;
1056						}
1057#endif
1058#ifdef SCTP_SNDRCV
1059					if (cmsg->cmsg_type == SCTP_SNDRCV)
1060						{
1061						struct sctp_sndrcvinfo *sndrcvinfo;
1062
1063						sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1064						data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
1065						data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
1066						data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
1067						data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
1068						data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
1069						data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
1070						data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
1071						}
1072#endif
1073					}
1074				}
1075
1076			if (n <= 0)
1077				{
1078				if (n < 0)
1079					ret = n;
1080				break;
1081				}
1082
1083			if (msg.msg_flags & MSG_NOTIFICATION)
1084				{
1085				snp = (union sctp_notification*) out;
1086				if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
1087					{
1088#ifdef SCTP_EVENT
1089					struct sctp_event event;
1090#else
1091					struct sctp_event_subscribe event;
1092					socklen_t eventsize;
1093#endif
1094					/* If a message has been delayed until the socket
1095					 * is dry, it can be sent now.
1096					 */
1097					if (data->saved_message.length > 0)
1098						{
1099						dgram_sctp_write(data->saved_message.bio, data->saved_message.data,
1100						                 data->saved_message.length);
1101						OPENSSL_free(data->saved_message.data);
1102						data->saved_message.length = 0;
1103						}
1104
1105					/* disable sender dry event */
1106#ifdef SCTP_EVENT
1107					memset(&event, 0, sizeof(struct sctp_event));
1108					event.se_assoc_id = 0;
1109					event.se_type = SCTP_SENDER_DRY_EVENT;
1110					event.se_on = 0;
1111					i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
1112					OPENSSL_assert(i >= 0);
1113#else
1114					eventsize = sizeof(struct sctp_event_subscribe);
1115					i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1116					OPENSSL_assert(i >= 0);
1117
1118					event.sctp_sender_dry_event = 0;
1119
1120					i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
1121					OPENSSL_assert(i >= 0);
1122#endif
1123					}
1124
1125#ifdef SCTP_AUTHENTICATION_EVENT
1126				if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1127					dgram_sctp_handle_auth_free_key_event(b, snp);
1128#endif
1129
1130				if (data->handle_notifications != NULL)
1131					data->handle_notifications(b, data->notification_context, (void*) out);
1132
1133				memset(out, 0, outl);
1134				}
1135			else
1136				ret += n;
1137			}
1138		while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl));
1139
1140		if (ret > 0 && !(msg.msg_flags & MSG_EOR))
1141			{
1142			/* Partial message read, this should never happen! */
1143
1144			/* The buffer was too small, this means the peer sent
1145			 * a message that was larger than allowed. */
1146			if (ret == outl)
1147				return -1;
1148
1149			/* Test if socket buffer can handle max record
1150			 * size (2^14 + 2048 + 13)
1151			 */
1152			optlen = (socklen_t) sizeof(int);
1153			ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
1154			OPENSSL_assert(ret >= 0);
1155			OPENSSL_assert(optval >= 18445);
1156
1157			/* Test if SCTP doesn't partially deliver below
1158			 * max record size (2^14 + 2048 + 13)
1159			 */
1160			optlen = (socklen_t) sizeof(int);
1161			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
1162			                 &optval, &optlen);
1163			OPENSSL_assert(ret >= 0);
1164			OPENSSL_assert(optval >= 18445);
1165
1166			/* Partially delivered notification??? Probably a bug.... */
1167			OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
1168
1169			/* Everything seems ok till now, so it's most likely
1170			 * a message dropped by PR-SCTP.
1171			 */
1172			memset(out, 0, outl);
1173			BIO_set_retry_read(b);
1174			return -1;
1175			}
1176
1177		BIO_clear_retry_flags(b);
1178		if (ret < 0)
1179			{
1180			if (BIO_dgram_should_retry(ret))
1181				{
1182				BIO_set_retry_read(b);
1183				data->_errno = get_last_socket_error();
1184				}
1185			}
1186
1187		/* Test if peer uses SCTP-AUTH before continuing */
1188		if (!data->peer_auth_tested)
1189			{
1190			int ii, auth_data = 0, auth_forward = 0;
1191			unsigned char *p;
1192			struct sctp_authchunks *authchunks;
1193
1194			optlen = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
1195			authchunks = OPENSSL_malloc(optlen);
1196			memset(authchunks, 0, sizeof(optlen));
1197			ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen);
1198			OPENSSL_assert(ii >= 0);
1199
1200			for (p = (unsigned char*) authchunks->gauth_chunks;
1201				 p < (unsigned char*) authchunks + optlen;
1202				 p += sizeof(uint8_t))
1203				{
1204				if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1;
1205				if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1;
1206				}
1207
1208			OPENSSL_free(authchunks);
1209
1210			if (!auth_data || !auth_forward)
1211				{
1212				BIOerr(BIO_F_DGRAM_SCTP_READ,BIO_R_CONNECT_ERROR);
1213				return -1;
1214				}
1215
1216			data->peer_auth_tested = 1;
1217			}
1218		}
1219	return(ret);
1220	}
1221
1222static int dgram_sctp_write(BIO *b, const char *in, int inl)
1223	{
1224	int ret;
1225	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
1226	struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
1227	struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
1228	struct bio_dgram_sctp_sndinfo handshake_sinfo;
1229	struct iovec iov[1];
1230	struct msghdr msg;
1231	struct cmsghdr *cmsg;
1232#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1233	char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + CMSG_SPACE(sizeof(struct sctp_prinfo))];
1234	struct sctp_sndinfo *sndinfo;
1235	struct sctp_prinfo *prinfo;
1236#else
1237	char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
1238	struct sctp_sndrcvinfo *sndrcvinfo;
1239#endif
1240
1241	clear_socket_error();
1242
1243	/* If we're send anything else than application data,
1244	 * disable all user parameters and flags.
1245	 */
1246	if (in[0] != 23) {
1247		memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo));
1248#ifdef SCTP_SACK_IMMEDIATELY
1249		handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
1250#endif
1251		sinfo = &handshake_sinfo;
1252	}
1253
1254	/* If we have to send a shutdown alert message and the
1255	 * socket is not dry yet, we have to save it and send it
1256	 * as soon as the socket gets dry.
1257	 */
1258	if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b))
1259	{
1260		data->saved_message.bio = b;
1261		data->saved_message.length = inl;
1262		data->saved_message.data = OPENSSL_malloc(inl);
1263		memcpy(data->saved_message.data, in, inl);
1264		return inl;
1265	}
1266
1267	iov[0].iov_base = (char *)in;
1268	iov[0].iov_len = inl;
1269	msg.msg_name = NULL;
1270	msg.msg_namelen = 0;
1271	msg.msg_iov = iov;
1272	msg.msg_iovlen = 1;
1273	msg.msg_control = (caddr_t)cmsgbuf;
1274	msg.msg_controllen = 0;
1275	msg.msg_flags = 0;
1276#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1277	cmsg = (struct cmsghdr *)cmsgbuf;
1278	cmsg->cmsg_level = IPPROTO_SCTP;
1279	cmsg->cmsg_type = SCTP_SNDINFO;
1280	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
1281	sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
1282	memset(sndinfo, 0, sizeof(struct sctp_sndinfo));
1283	sndinfo->snd_sid = sinfo->snd_sid;
1284	sndinfo->snd_flags = sinfo->snd_flags;
1285	sndinfo->snd_ppid = sinfo->snd_ppid;
1286	sndinfo->snd_context = sinfo->snd_context;
1287	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
1288
1289	cmsg = (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
1290	cmsg->cmsg_level = IPPROTO_SCTP;
1291	cmsg->cmsg_type = SCTP_PRINFO;
1292	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
1293	prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
1294	memset(prinfo, 0, sizeof(struct sctp_prinfo));
1295	prinfo->pr_policy = pinfo->pr_policy;
1296	prinfo->pr_value = pinfo->pr_value;
1297	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
1298#else
1299	cmsg = (struct cmsghdr *)cmsgbuf;
1300	cmsg->cmsg_level = IPPROTO_SCTP;
1301	cmsg->cmsg_type = SCTP_SNDRCV;
1302	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
1303	sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1304	memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
1305	sndrcvinfo->sinfo_stream = sinfo->snd_sid;
1306	sndrcvinfo->sinfo_flags = sinfo->snd_flags;
1307#ifdef __FreeBSD__
1308	sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
1309#endif
1310	sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
1311	sndrcvinfo->sinfo_context = sinfo->snd_context;
1312	sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
1313	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
1314#endif
1315
1316	ret = sendmsg(b->num, &msg, 0);
1317
1318	BIO_clear_retry_flags(b);
1319	if (ret <= 0)
1320		{
1321		if (BIO_dgram_should_retry(ret))
1322			{
1323			BIO_set_retry_write(b);
1324			data->_errno = get_last_socket_error();
1325			}
1326		}
1327	return(ret);
1328	}
1329
1330static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1331	{
1332	long ret=1;
1333	bio_dgram_sctp_data *data = NULL;
1334	socklen_t sockopt_len = 0;
1335	struct sctp_authkeyid authkeyid;
1336	struct sctp_authkey *authkey = NULL;
1337
1338	data = (bio_dgram_sctp_data *)b->ptr;
1339
1340	switch (cmd)
1341		{
1342	case BIO_CTRL_DGRAM_QUERY_MTU:
1343		/* Set to maximum (2^14)
1344		 * and ignore user input to enable transport
1345		 * protocol fragmentation.
1346		 * Returns always 2^14.
1347		 */
1348		data->mtu = 16384;
1349		ret = data->mtu;
1350		break;
1351	case BIO_CTRL_DGRAM_SET_MTU:
1352		/* Set to maximum (2^14)
1353		 * and ignore input to enable transport
1354		 * protocol fragmentation.
1355		 * Returns always 2^14.
1356		 */
1357		data->mtu = 16384;
1358		ret = data->mtu;
1359		break;
1360	case BIO_CTRL_DGRAM_SET_CONNECTED:
1361	case BIO_CTRL_DGRAM_CONNECT:
1362		/* Returns always -1. */
1363		ret = -1;
1364		break;
1365	case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
1366		/* SCTP doesn't need the DTLS timer
1367		 * Returns always 1.
1368		 */
1369		break;
1370	case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
1371		if (num > 0)
1372			data->in_handshake = 1;
1373		else
1374			data->in_handshake = 0;
1375
1376		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY, &data->in_handshake, sizeof(int));
1377		break;
1378	case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
1379		/* New shared key for SCTP AUTH.
1380		 * Returns 0 on success, -1 otherwise.
1381		 */
1382
1383		/* Get active key */
1384		sockopt_len = sizeof(struct sctp_authkeyid);
1385		ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1386		if (ret < 0) break;
1387
1388		/* Add new key */
1389		sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
1390		authkey = OPENSSL_malloc(sockopt_len);
1391		if (authkey == NULL)
1392			{
1393			ret = -1;
1394			break;
1395			}
1396		memset(authkey, 0x00, sockopt_len);
1397		authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
1398#ifndef __FreeBSD__
1399		/* This field is missing in FreeBSD 8.2 and earlier,
1400		 * and FreeBSD 8.3 and higher work without it.
1401		 */
1402		authkey->sca_keylength = 64;
1403#endif
1404		memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
1405
1406		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len);
1407		OPENSSL_free(authkey);
1408		authkey = NULL;
1409		if (ret < 0) break;
1410
1411		/* Reset active key */
1412		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1413		      &authkeyid, sizeof(struct sctp_authkeyid));
1414		if (ret < 0) break;
1415
1416		break;
1417	case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
1418		/* Returns 0 on success, -1 otherwise. */
1419
1420		/* Get active key */
1421		sockopt_len = sizeof(struct sctp_authkeyid);
1422		ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1423		if (ret < 0) break;
1424
1425		/* Set active key */
1426		authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
1427		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1428		      &authkeyid, sizeof(struct sctp_authkeyid));
1429		if (ret < 0) break;
1430
1431		/* CCS has been sent, so remember that and fall through
1432		 * to check if we need to deactivate an old key
1433		 */
1434		data->ccs_sent = 1;
1435
1436	case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
1437		/* Returns 0 on success, -1 otherwise. */
1438
1439		/* Has this command really been called or is this just a fall-through? */
1440		if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
1441			data->ccs_rcvd = 1;
1442
1443		/* CSS has been both, received and sent, so deactivate an old key */
1444		if (data->ccs_rcvd == 1 && data->ccs_sent == 1)
1445			{
1446			/* Get active key */
1447			sockopt_len = sizeof(struct sctp_authkeyid);
1448			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1449			if (ret < 0) break;
1450
1451			/* Deactivate key or delete second last key if
1452			 * SCTP_AUTHENTICATION_EVENT is not available.
1453			 */
1454			authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
1455#ifdef SCTP_AUTH_DEACTIVATE_KEY
1456			sockopt_len = sizeof(struct sctp_authkeyid);
1457			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
1458			      &authkeyid, sockopt_len);
1459			if (ret < 0) break;
1460#endif
1461#ifndef SCTP_AUTHENTICATION_EVENT
1462			if (authkeyid.scact_keynumber > 0)
1463				{
1464				authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
1465				ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
1466					  &authkeyid, sizeof(struct sctp_authkeyid));
1467				if (ret < 0) break;
1468				}
1469#endif
1470
1471			data->ccs_rcvd = 0;
1472			data->ccs_sent = 0;
1473			}
1474		break;
1475	case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
1476		/* Returns the size of the copied struct. */
1477		if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo))
1478			num = sizeof(struct bio_dgram_sctp_sndinfo);
1479
1480		memcpy(ptr, &(data->sndinfo), num);
1481		ret = num;
1482		break;
1483	case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
1484		/* Returns the size of the copied struct. */
1485		if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo))
1486			num = sizeof(struct bio_dgram_sctp_sndinfo);
1487
1488		memcpy(&(data->sndinfo), ptr, num);
1489		break;
1490	case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
1491		/* Returns the size of the copied struct. */
1492		if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
1493			num = sizeof(struct bio_dgram_sctp_rcvinfo);
1494
1495		memcpy(ptr, &data->rcvinfo, num);
1496
1497		ret = num;
1498		break;
1499	case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
1500		/* Returns the size of the copied struct. */
1501		if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
1502			num = sizeof(struct bio_dgram_sctp_rcvinfo);
1503
1504		memcpy(&(data->rcvinfo), ptr, num);
1505		break;
1506	case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
1507		/* Returns the size of the copied struct. */
1508		if (num > (long) sizeof(struct bio_dgram_sctp_prinfo))
1509			num = sizeof(struct bio_dgram_sctp_prinfo);
1510
1511		memcpy(ptr, &(data->prinfo), num);
1512		ret = num;
1513		break;
1514	case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
1515		/* Returns the size of the copied struct. */
1516		if (num > (long) sizeof(struct bio_dgram_sctp_prinfo))
1517			num = sizeof(struct bio_dgram_sctp_prinfo);
1518
1519		memcpy(&(data->prinfo), ptr, num);
1520		break;
1521	case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
1522		/* Returns always 1. */
1523		if (num > 0)
1524			data->save_shutdown = 1;
1525		else
1526			data->save_shutdown = 0;
1527		break;
1528
1529	default:
1530		/* Pass to default ctrl function to
1531		 * process SCTP unspecific commands
1532		 */
1533		ret=dgram_ctrl(b, cmd, num, ptr);
1534		break;
1535		}
1536	return(ret);
1537	}
1538
1539int BIO_dgram_sctp_notification_cb(BIO *b,
1540                                   void (*handle_notifications)(BIO *bio, void *context, void *buf),
1541                                   void *context)
1542	{
1543	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1544
1545	if (handle_notifications != NULL)
1546		{
1547		data->handle_notifications = handle_notifications;
1548		data->notification_context = context;
1549		}
1550	else
1551		return -1;
1552
1553	return 0;
1554	}
1555
1556int BIO_dgram_sctp_wait_for_dry(BIO *b)
1557{
1558	int is_dry = 0;
1559	int n, sockflags, ret;
1560	union sctp_notification snp;
1561	struct msghdr msg;
1562	struct iovec iov;
1563#ifdef SCTP_EVENT
1564	struct sctp_event event;
1565#else
1566	struct sctp_event_subscribe event;
1567	socklen_t eventsize;
1568#endif
1569	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
1570
1571	/* set sender dry event */
1572#ifdef SCTP_EVENT
1573	memset(&event, 0, sizeof(struct sctp_event));
1574	event.se_assoc_id = 0;
1575	event.se_type = SCTP_SENDER_DRY_EVENT;
1576	event.se_on = 1;
1577	ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
1578#else
1579	eventsize = sizeof(struct sctp_event_subscribe);
1580	ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1581	if (ret < 0)
1582		return -1;
1583
1584	event.sctp_sender_dry_event = 1;
1585
1586	ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
1587#endif
1588	if (ret < 0)
1589		return -1;
1590
1591	/* peek for notification */
1592	memset(&snp, 0x00, sizeof(union sctp_notification));
1593	iov.iov_base = (char *)&snp;
1594	iov.iov_len = sizeof(union sctp_notification);
1595	msg.msg_name = NULL;
1596	msg.msg_namelen = 0;
1597	msg.msg_iov = &iov;
1598	msg.msg_iovlen = 1;
1599	msg.msg_control = NULL;
1600	msg.msg_controllen = 0;
1601	msg.msg_flags = 0;
1602
1603	n = recvmsg(b->num, &msg, MSG_PEEK);
1604	if (n <= 0)
1605		{
1606		if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
1607			return -1;
1608		else
1609			return 0;
1610		}
1611
1612	/* if we find a notification, process it and try again if necessary */
1613	while (msg.msg_flags & MSG_NOTIFICATION)
1614		{
1615		memset(&snp, 0x00, sizeof(union sctp_notification));
1616		iov.iov_base = (char *)&snp;
1617		iov.iov_len = sizeof(union sctp_notification);
1618		msg.msg_name = NULL;
1619		msg.msg_namelen = 0;
1620		msg.msg_iov = &iov;
1621		msg.msg_iovlen = 1;
1622		msg.msg_control = NULL;
1623		msg.msg_controllen = 0;
1624		msg.msg_flags = 0;
1625
1626		n = recvmsg(b->num, &msg, 0);
1627		if (n <= 0)
1628			{
1629			if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
1630				return -1;
1631			else
1632				return is_dry;
1633			}
1634
1635		if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
1636			{
1637			is_dry = 1;
1638
1639			/* disable sender dry event */
1640#ifdef SCTP_EVENT
1641			memset(&event, 0, sizeof(struct sctp_event));
1642			event.se_assoc_id = 0;
1643			event.se_type = SCTP_SENDER_DRY_EVENT;
1644			event.se_on = 0;
1645			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
1646#else
1647			eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
1648			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1649			if (ret < 0)
1650				return -1;
1651
1652			event.sctp_sender_dry_event = 0;
1653
1654			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
1655#endif
1656			if (ret < 0)
1657				return -1;
1658			}
1659
1660#ifdef SCTP_AUTHENTICATION_EVENT
1661		if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1662			dgram_sctp_handle_auth_free_key_event(b, &snp);
1663#endif
1664
1665		if (data->handle_notifications != NULL)
1666			data->handle_notifications(b, data->notification_context, (void*) &snp);
1667
1668		/* found notification, peek again */
1669		memset(&snp, 0x00, sizeof(union sctp_notification));
1670		iov.iov_base = (char *)&snp;
1671		iov.iov_len = sizeof(union sctp_notification);
1672		msg.msg_name = NULL;
1673		msg.msg_namelen = 0;
1674		msg.msg_iov = &iov;
1675		msg.msg_iovlen = 1;
1676		msg.msg_control = NULL;
1677		msg.msg_controllen = 0;
1678		msg.msg_flags = 0;
1679
1680		/* if we have seen the dry already, don't wait */
1681		if (is_dry)
1682			{
1683			sockflags = fcntl(b->num, F_GETFL, 0);
1684			fcntl(b->num, F_SETFL, O_NONBLOCK);
1685			}
1686
1687		n = recvmsg(b->num, &msg, MSG_PEEK);
1688
1689		if (is_dry)
1690			{
1691			fcntl(b->num, F_SETFL, sockflags);
1692			}
1693
1694		if (n <= 0)
1695			{
1696			if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
1697				return -1;
1698			else
1699				return is_dry;
1700			}
1701		}
1702
1703	/* read anything else */
1704	return is_dry;
1705}
1706
1707int BIO_dgram_sctp_msg_waiting(BIO *b)
1708	{
1709	int n, sockflags;
1710	union sctp_notification snp;
1711	struct msghdr msg;
1712	struct iovec iov;
1713	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
1714
1715	/* Check if there are any messages waiting to be read */
1716	do
1717		{
1718		memset(&snp, 0x00, sizeof(union sctp_notification));
1719		iov.iov_base = (char *)&snp;
1720		iov.iov_len = sizeof(union sctp_notification);
1721		msg.msg_name = NULL;
1722		msg.msg_namelen = 0;
1723		msg.msg_iov = &iov;
1724		msg.msg_iovlen = 1;
1725		msg.msg_control = NULL;
1726		msg.msg_controllen = 0;
1727		msg.msg_flags = 0;
1728
1729		sockflags = fcntl(b->num, F_GETFL, 0);
1730		fcntl(b->num, F_SETFL, O_NONBLOCK);
1731		n = recvmsg(b->num, &msg, MSG_PEEK);
1732		fcntl(b->num, F_SETFL, sockflags);
1733
1734		/* if notification, process and try again */
1735		if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION))
1736			{
1737#ifdef SCTP_AUTHENTICATION_EVENT
1738			if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1739				dgram_sctp_handle_auth_free_key_event(b, &snp);
1740#endif
1741
1742			memset(&snp, 0x00, sizeof(union sctp_notification));
1743			iov.iov_base = (char *)&snp;
1744			iov.iov_len = sizeof(union sctp_notification);
1745			msg.msg_name = NULL;
1746			msg.msg_namelen = 0;
1747			msg.msg_iov = &iov;
1748			msg.msg_iovlen = 1;
1749			msg.msg_control = NULL;
1750			msg.msg_controllen = 0;
1751			msg.msg_flags = 0;
1752			n = recvmsg(b->num, &msg, 0);
1753
1754			if (data->handle_notifications != NULL)
1755				data->handle_notifications(b, data->notification_context, (void*) &snp);
1756			}
1757
1758		} while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
1759
1760	/* Return 1 if there is a message to be read, return 0 otherwise. */
1761	if (n > 0)
1762		return 1;
1763	else
1764		return 0;
1765	}
1766
1767static int dgram_sctp_puts(BIO *bp, const char *str)
1768	{
1769	int n,ret;
1770
1771	n=strlen(str);
1772	ret=dgram_sctp_write(bp,str,n);
1773	return(ret);
1774	}
1775#endif
1776
1777static int BIO_dgram_should_retry(int i)
1778	{
1779	int err;
1780
1781	if ((i == 0) || (i == -1))
1782		{
1783		err=get_last_socket_error();
1784
1785#if defined(OPENSSL_SYS_WINDOWS)
1786	/* If the socket return value (i) is -1
1787	 * and err is unexpectedly 0 at this point,
1788	 * the error code was overwritten by
1789	 * another system call before this error
1790	 * handling is called.
1791	 */
1792#endif
1793
1794		return(BIO_dgram_non_fatal_error(err));
1795		}
1796	return(0);
1797	}
1798
1799int BIO_dgram_non_fatal_error(int err)
1800	{
1801	switch (err)
1802		{
1803#if defined(OPENSSL_SYS_WINDOWS)
1804# if defined(WSAEWOULDBLOCK)
1805	case WSAEWOULDBLOCK:
1806# endif
1807
1808# if 0 /* This appears to always be an error */
1809#  if defined(WSAENOTCONN)
1810	case WSAENOTCONN:
1811#  endif
1812# endif
1813#endif
1814
1815#ifdef EWOULDBLOCK
1816# ifdef WSAEWOULDBLOCK
1817#  if WSAEWOULDBLOCK != EWOULDBLOCK
1818	case EWOULDBLOCK:
1819#  endif
1820# else
1821	case EWOULDBLOCK:
1822# endif
1823#endif
1824
1825#ifdef EINTR
1826	case EINTR:
1827#endif
1828
1829#ifdef EAGAIN
1830#if EWOULDBLOCK != EAGAIN
1831	case EAGAIN:
1832# endif
1833#endif
1834
1835#ifdef EPROTO
1836	case EPROTO:
1837#endif
1838
1839#ifdef EINPROGRESS
1840	case EINPROGRESS:
1841#endif
1842
1843#ifdef EALREADY
1844	case EALREADY:
1845#endif
1846
1847		return(1);
1848		/* break; */
1849	default:
1850		break;
1851		}
1852	return(0);
1853	}
1854
1855static void get_current_time(struct timeval *t)
1856	{
1857#ifdef OPENSSL_SYS_WIN32
1858	struct _timeb tb;
1859	_ftime(&tb);
1860	t->tv_sec = (long)tb.time;
1861	t->tv_usec = (long)tb.millitm * 1000;
1862#elif defined(OPENSSL_SYS_VMS)
1863	struct timeb tb;
1864	ftime(&tb);
1865	t->tv_sec = (long)tb.time;
1866	t->tv_usec = (long)tb.millitm * 1000;
1867#else
1868	gettimeofday(t, NULL);
1869#endif
1870	}
1871
1872#endif
1873