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