bss_dgram.c revision 279264
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_get_mtu_overhead(bio_dgram_data *data)
458	{
459	long ret;
460
461	switch (data->peer.sa.sa_family)
462		{
463		case AF_INET:
464			/* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP */
465			ret = 28;
466			break;
467#if OPENSSL_USE_IPV6
468		case AF_INET6:
469#ifdef IN6_IS_ADDR_V4MAPPED
470			if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
471				/* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP */
472				ret = 28;
473			else
474#endif
475				/* Assume this is UDP - 40 bytes for IP, 8 bytes for UDP */
476				ret = 48;
477			break;
478#endif
479		default:
480			/* We don't know. Go with the historical default */
481			ret = 28;
482			break;
483		}
484	return ret;
485	}
486
487static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
488	{
489	long ret=1;
490	int *ip;
491	struct sockaddr *to = NULL;
492	bio_dgram_data *data = NULL;
493#if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
494	int sockopt_val = 0;
495	socklen_t sockopt_len;	/* assume that system supporting IP_MTU is
496				 * modern enough to define socklen_t */
497	socklen_t addr_len;
498	union	{
499		struct sockaddr	sa;
500		struct sockaddr_in s4;
501#if OPENSSL_USE_IPV6
502		struct sockaddr_in6 s6;
503#endif
504		} addr;
505#endif
506
507	data = (bio_dgram_data *)b->ptr;
508
509	switch (cmd)
510		{
511	case BIO_CTRL_RESET:
512		num=0;
513	case BIO_C_FILE_SEEK:
514		ret=0;
515		break;
516	case BIO_C_FILE_TELL:
517	case BIO_CTRL_INFO:
518		ret=0;
519		break;
520	case BIO_C_SET_FD:
521		dgram_clear(b);
522		b->num= *((int *)ptr);
523		b->shutdown=(int)num;
524		b->init=1;
525		break;
526	case BIO_C_GET_FD:
527		if (b->init)
528			{
529			ip=(int *)ptr;
530			if (ip != NULL) *ip=b->num;
531			ret=b->num;
532			}
533		else
534			ret= -1;
535		break;
536	case BIO_CTRL_GET_CLOSE:
537		ret=b->shutdown;
538		break;
539	case BIO_CTRL_SET_CLOSE:
540		b->shutdown=(int)num;
541		break;
542	case BIO_CTRL_PENDING:
543	case BIO_CTRL_WPENDING:
544		ret=0;
545		break;
546	case BIO_CTRL_DUP:
547	case BIO_CTRL_FLUSH:
548		ret=1;
549		break;
550	case BIO_CTRL_DGRAM_CONNECT:
551		to = (struct sockaddr *)ptr;
552#if 0
553		if (connect(b->num, to, sizeof(struct sockaddr)) < 0)
554			{ perror("connect"); ret = 0; }
555		else
556			{
557#endif
558			switch (to->sa_family)
559				{
560				case AF_INET:
561					memcpy(&data->peer,to,sizeof(data->peer.sa_in));
562					break;
563#if OPENSSL_USE_IPV6
564				case AF_INET6:
565					memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
566					break;
567#endif
568				default:
569					memcpy(&data->peer,to,sizeof(data->peer.sa));
570					break;
571				}
572#if 0
573			}
574#endif
575		break;
576		/* (Linux)kernel sets DF bit on outgoing IP packets */
577	case BIO_CTRL_DGRAM_MTU_DISCOVER:
578#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
579		addr_len = (socklen_t)sizeof(addr);
580		memset((void *)&addr, 0, sizeof(addr));
581		if (getsockname(b->num, &addr.sa, &addr_len) < 0)
582			{
583			ret = 0;
584			break;
585			}
586		switch (addr.sa.sa_family)
587			{
588		case AF_INET:
589			sockopt_val = IP_PMTUDISC_DO;
590			if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
591				&sockopt_val, sizeof(sockopt_val))) < 0)
592				perror("setsockopt");
593			break;
594#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
595		case AF_INET6:
596			sockopt_val = IPV6_PMTUDISC_DO;
597			if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
598				&sockopt_val, sizeof(sockopt_val))) < 0)
599				perror("setsockopt");
600			break;
601#endif
602		default:
603			ret = -1;
604			break;
605			}
606		ret = -1;
607#else
608		break;
609#endif
610	case BIO_CTRL_DGRAM_QUERY_MTU:
611#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
612		addr_len = (socklen_t)sizeof(addr);
613		memset((void *)&addr, 0, sizeof(addr));
614		if (getsockname(b->num, &addr.sa, &addr_len) < 0)
615			{
616			ret = 0;
617			break;
618			}
619		sockopt_len = sizeof(sockopt_val);
620		switch (addr.sa.sa_family)
621			{
622		case AF_INET:
623			if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
624				&sockopt_len)) < 0 || sockopt_val < 0)
625				{
626				ret = 0;
627				}
628			else
629				{
630				/* we assume that the transport protocol is UDP and no
631				 * IP options are used.
632				 */
633				data->mtu = sockopt_val - 8 - 20;
634				ret = data->mtu;
635				}
636			break;
637#if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
638		case AF_INET6:
639			if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val,
640				&sockopt_len)) < 0 || sockopt_val < 0)
641				{
642				ret = 0;
643				}
644			else
645				{
646				/* we assume that the transport protocol is UDP and no
647				 * IPV6 options are used.
648				 */
649				data->mtu = sockopt_val - 8 - 40;
650				ret = data->mtu;
651				}
652			break;
653#endif
654		default:
655			ret = 0;
656			break;
657			}
658#else
659		ret = 0;
660#endif
661		break;
662	case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
663		ret = -dgram_get_mtu_overhead(data);
664		switch (data->peer.sa.sa_family)
665			{
666			case AF_INET:
667				ret += 576;
668				break;
669#if OPENSSL_USE_IPV6
670			case AF_INET6:
671#ifdef IN6_IS_ADDR_V4MAPPED
672				if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
673					ret += 576;
674				else
675#endif
676					ret += 1280;
677				break;
678#endif
679			default:
680				ret += 576;
681				break;
682			}
683		break;
684	case BIO_CTRL_DGRAM_GET_MTU:
685		return data->mtu;
686		break;
687	case BIO_CTRL_DGRAM_SET_MTU:
688		data->mtu = num;
689		ret = num;
690		break;
691	case BIO_CTRL_DGRAM_SET_CONNECTED:
692		to = (struct sockaddr *)ptr;
693
694		if ( to != NULL)
695			{
696			data->connected = 1;
697			switch (to->sa_family)
698				{
699				case AF_INET:
700					memcpy(&data->peer,to,sizeof(data->peer.sa_in));
701					break;
702#if OPENSSL_USE_IPV6
703				case AF_INET6:
704					memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
705					break;
706#endif
707				default:
708					memcpy(&data->peer,to,sizeof(data->peer.sa));
709					break;
710				}
711			}
712		else
713			{
714			data->connected = 0;
715			memset(&(data->peer), 0x00, sizeof(data->peer));
716			}
717		break;
718	case BIO_CTRL_DGRAM_GET_PEER:
719		switch (data->peer.sa.sa_family)
720			{
721			case AF_INET:
722				ret=sizeof(data->peer.sa_in);
723				break;
724#if OPENSSL_USE_IPV6
725			case AF_INET6:
726				ret=sizeof(data->peer.sa_in6);
727				break;
728#endif
729			default:
730				ret=sizeof(data->peer.sa);
731				break;
732			}
733		if (num==0 || num>ret)
734			num=ret;
735		memcpy(ptr,&data->peer,(ret=num));
736		break;
737	case BIO_CTRL_DGRAM_SET_PEER:
738		to = (struct sockaddr *) ptr;
739		switch (to->sa_family)
740			{
741			case AF_INET:
742				memcpy(&data->peer,to,sizeof(data->peer.sa_in));
743				break;
744#if OPENSSL_USE_IPV6
745			case AF_INET6:
746				memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
747				break;
748#endif
749			default:
750				memcpy(&data->peer,to,sizeof(data->peer.sa));
751				break;
752			}
753		break;
754	case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
755		memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
756		break;
757#if defined(SO_RCVTIMEO)
758	case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
759#ifdef OPENSSL_SYS_WINDOWS
760		{
761		struct timeval *tv = (struct timeval *)ptr;
762		int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
763		if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
764			(void*)&timeout, sizeof(timeout)) < 0)
765			{ perror("setsockopt"); ret = -1; }
766		}
767#else
768		if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
769			sizeof(struct timeval)) < 0)
770			{ perror("setsockopt");	ret = -1; }
771#endif
772		break;
773	case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
774		{
775		union { size_t s; int i; } sz = {0};
776#ifdef OPENSSL_SYS_WINDOWS
777		int timeout;
778		struct timeval *tv = (struct timeval *)ptr;
779
780		sz.i = sizeof(timeout);
781		if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
782			(void*)&timeout, &sz.i) < 0)
783			{ perror("getsockopt"); ret = -1; }
784		else
785			{
786			tv->tv_sec = timeout / 1000;
787			tv->tv_usec = (timeout % 1000) * 1000;
788			ret = sizeof(*tv);
789			}
790#else
791		sz.i = sizeof(struct timeval);
792		if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
793			ptr, (void *)&sz) < 0)
794			{ perror("getsockopt"); ret = -1; }
795		else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
796			{
797			OPENSSL_assert(sz.s<=sizeof(struct timeval));
798			ret = (int)sz.s;
799			}
800		else
801			ret = sz.i;
802#endif
803		}
804		break;
805#endif
806#if defined(SO_SNDTIMEO)
807	case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
808#ifdef OPENSSL_SYS_WINDOWS
809		{
810		struct timeval *tv = (struct timeval *)ptr;
811		int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
812		if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
813			(void*)&timeout, sizeof(timeout)) < 0)
814			{ perror("setsockopt"); ret = -1; }
815		}
816#else
817		if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
818			sizeof(struct timeval)) < 0)
819			{ perror("setsockopt");	ret = -1; }
820#endif
821		break;
822	case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
823		{
824		union { size_t s; int i; } sz = {0};
825#ifdef OPENSSL_SYS_WINDOWS
826		int timeout;
827		struct timeval *tv = (struct timeval *)ptr;
828
829		sz.i = sizeof(timeout);
830		if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
831			(void*)&timeout, &sz.i) < 0)
832			{ perror("getsockopt"); ret = -1; }
833		else
834			{
835			tv->tv_sec = timeout / 1000;
836			tv->tv_usec = (timeout % 1000) * 1000;
837			ret = sizeof(*tv);
838			}
839#else
840		sz.i = sizeof(struct timeval);
841		if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
842			ptr, (void *)&sz) < 0)
843			{ perror("getsockopt"); ret = -1; }
844		else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
845			{
846			OPENSSL_assert(sz.s<=sizeof(struct timeval));
847			ret = (int)sz.s;
848			}
849		else
850			ret = sz.i;
851#endif
852		}
853		break;
854#endif
855	case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
856		/* fall-through */
857	case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
858#ifdef OPENSSL_SYS_WINDOWS
859		if ( data->_errno == WSAETIMEDOUT)
860#else
861		if ( data->_errno == EAGAIN)
862#endif
863			{
864			ret = 1;
865			data->_errno = 0;
866			}
867		else
868			ret = 0;
869		break;
870#ifdef EMSGSIZE
871	case BIO_CTRL_DGRAM_MTU_EXCEEDED:
872		if ( data->_errno == EMSGSIZE)
873			{
874			ret = 1;
875			data->_errno = 0;
876			}
877		else
878			ret = 0;
879		break;
880#endif
881	case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
882		ret = dgram_get_mtu_overhead(data);
883		break;
884	default:
885		ret=0;
886		break;
887		}
888	return(ret);
889	}
890
891static int dgram_puts(BIO *bp, const char *str)
892	{
893	int n,ret;
894
895	n=strlen(str);
896	ret=dgram_write(bp,str,n);
897	return(ret);
898	}
899
900#ifndef OPENSSL_NO_SCTP
901BIO_METHOD *BIO_s_datagram_sctp(void)
902	{
903	return(&methods_dgramp_sctp);
904	}
905
906BIO *BIO_new_dgram_sctp(int fd, int close_flag)
907	{
908	BIO *bio;
909	int ret, optval = 20000;
910	int auth_data = 0, auth_forward = 0;
911	unsigned char *p;
912	struct sctp_authchunk auth;
913	struct sctp_authchunks *authchunks;
914	socklen_t sockopt_len;
915#ifdef SCTP_AUTHENTICATION_EVENT
916#ifdef SCTP_EVENT
917	struct sctp_event event;
918#else
919	struct sctp_event_subscribe event;
920#endif
921#endif
922
923	bio=BIO_new(BIO_s_datagram_sctp());
924	if (bio == NULL) return(NULL);
925	BIO_set_fd(bio,fd,close_flag);
926
927	/* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
928	auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
929	ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk));
930	if (ret < 0)
931		{
932		BIO_vfree(bio);
933		return(NULL);
934		}
935	auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
936	ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk));
937	if (ret < 0)
938		{
939		BIO_vfree(bio);
940		return(NULL);
941		}
942
943	/* Test if activation was successful. When using accept(),
944	 * SCTP-AUTH has to be activated for the listening socket
945	 * already, otherwise the connected socket won't use it. */
946	sockopt_len = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
947	authchunks = OPENSSL_malloc(sockopt_len);
948	memset(authchunks, 0, sizeof(sockopt_len));
949	ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, &sockopt_len);
950
951	if (ret < 0)
952		{
953		OPENSSL_free(authchunks);
954		BIO_vfree(bio);
955		return(NULL);
956		}
957
958	for (p = (unsigned char*) authchunks->gauth_chunks;
959	     p < (unsigned char*) authchunks + sockopt_len;
960	     p += sizeof(uint8_t))
961		{
962		if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1;
963		if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1;
964		}
965
966	OPENSSL_free(authchunks);
967
968	OPENSSL_assert(auth_data);
969	OPENSSL_assert(auth_forward);
970
971#ifdef SCTP_AUTHENTICATION_EVENT
972#ifdef SCTP_EVENT
973	memset(&event, 0, sizeof(struct sctp_event));
974	event.se_assoc_id = 0;
975	event.se_type = SCTP_AUTHENTICATION_EVENT;
976	event.se_on = 1;
977	ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
978	if (ret < 0)
979		{
980		BIO_vfree(bio);
981		return(NULL);
982		}
983#else
984	sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
985	ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
986	if (ret < 0)
987		{
988		BIO_vfree(bio);
989		return(NULL);
990		}
991
992	event.sctp_authentication_event = 1;
993
994	ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
995	if (ret < 0)
996		{
997		BIO_vfree(bio);
998		return(NULL);
999		}
1000#endif
1001#endif
1002
1003	/* Disable partial delivery by setting the min size
1004	 * larger than the max record size of 2^14 + 2048 + 13
1005	 */
1006	ret = setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, sizeof(optval));
1007	if (ret < 0)
1008		{
1009		BIO_vfree(bio);
1010		return(NULL);
1011		}
1012
1013	return(bio);
1014	}
1015
1016int BIO_dgram_is_sctp(BIO *bio)
1017	{
1018	return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
1019	}
1020
1021static int dgram_sctp_new(BIO *bi)
1022	{
1023	bio_dgram_sctp_data *data = NULL;
1024
1025	bi->init=0;
1026	bi->num=0;
1027	data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data));
1028	if (data == NULL)
1029		return 0;
1030	memset(data, 0x00, sizeof(bio_dgram_sctp_data));
1031#ifdef SCTP_PR_SCTP_NONE
1032	data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
1033#endif
1034    bi->ptr = data;
1035
1036	bi->flags=0;
1037	return(1);
1038	}
1039
1040static int dgram_sctp_free(BIO *a)
1041	{
1042	bio_dgram_sctp_data *data;
1043
1044	if (a == NULL) return(0);
1045	if ( ! dgram_clear(a))
1046		return 0;
1047
1048	data = (bio_dgram_sctp_data *)a->ptr;
1049	if(data != NULL)
1050		{
1051		if(data->saved_message.data != NULL)
1052			OPENSSL_free(data->saved_message.data);
1053		OPENSSL_free(data);
1054		}
1055
1056	return(1);
1057	}
1058
1059#ifdef SCTP_AUTHENTICATION_EVENT
1060void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
1061	{
1062	int ret;
1063	struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event;
1064
1065	if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY)
1066		{
1067		struct sctp_authkeyid authkeyid;
1068
1069		/* delete key */
1070		authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
1071		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
1072		      &authkeyid, sizeof(struct sctp_authkeyid));
1073		}
1074	}
1075#endif
1076
1077static int dgram_sctp_read(BIO *b, char *out, int outl)
1078	{
1079	int ret = 0, n = 0, i, optval;
1080	socklen_t optlen;
1081	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
1082	union sctp_notification *snp;
1083	struct msghdr msg;
1084	struct iovec iov;
1085	struct cmsghdr *cmsg;
1086	char cmsgbuf[512];
1087
1088	if (out != NULL)
1089		{
1090		clear_socket_error();
1091
1092		do
1093			{
1094			memset(&data->rcvinfo, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo));
1095			iov.iov_base = out;
1096			iov.iov_len = outl;
1097			msg.msg_name = NULL;
1098			msg.msg_namelen = 0;
1099			msg.msg_iov = &iov;
1100			msg.msg_iovlen = 1;
1101			msg.msg_control = cmsgbuf;
1102			msg.msg_controllen = 512;
1103			msg.msg_flags = 0;
1104			n = recvmsg(b->num, &msg, 0);
1105
1106			if (n <= 0)
1107				{
1108				if (n < 0)
1109					ret = n;
1110				break;
1111				}
1112
1113			if (msg.msg_controllen > 0)
1114				{
1115				for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
1116					{
1117					if (cmsg->cmsg_level != IPPROTO_SCTP)
1118						continue;
1119#ifdef SCTP_RCVINFO
1120					if (cmsg->cmsg_type == SCTP_RCVINFO)
1121						{
1122						struct sctp_rcvinfo *rcvinfo;
1123
1124						rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
1125						data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
1126						data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
1127						data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
1128						data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
1129						data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
1130						data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
1131						data->rcvinfo.rcv_context = rcvinfo->rcv_context;
1132						}
1133#endif
1134#ifdef SCTP_SNDRCV
1135					if (cmsg->cmsg_type == SCTP_SNDRCV)
1136						{
1137						struct sctp_sndrcvinfo *sndrcvinfo;
1138
1139						sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1140						data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
1141						data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
1142						data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
1143						data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
1144						data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
1145						data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
1146						data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
1147						}
1148#endif
1149					}
1150				}
1151
1152			if (msg.msg_flags & MSG_NOTIFICATION)
1153				{
1154				snp = (union sctp_notification*) out;
1155				if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
1156					{
1157#ifdef SCTP_EVENT
1158					struct sctp_event event;
1159#else
1160					struct sctp_event_subscribe event;
1161					socklen_t eventsize;
1162#endif
1163					/* If a message has been delayed until the socket
1164					 * is dry, it can be sent now.
1165					 */
1166					if (data->saved_message.length > 0)
1167						{
1168						dgram_sctp_write(data->saved_message.bio, data->saved_message.data,
1169						                 data->saved_message.length);
1170						OPENSSL_free(data->saved_message.data);
1171						data->saved_message.data = NULL;
1172						data->saved_message.length = 0;
1173						}
1174
1175					/* disable sender dry event */
1176#ifdef SCTP_EVENT
1177					memset(&event, 0, sizeof(struct sctp_event));
1178					event.se_assoc_id = 0;
1179					event.se_type = SCTP_SENDER_DRY_EVENT;
1180					event.se_on = 0;
1181					i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
1182					if (i < 0)
1183						{
1184						ret = i;
1185						break;
1186						}
1187#else
1188					eventsize = sizeof(struct sctp_event_subscribe);
1189					i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1190					if (i < 0)
1191						{
1192						ret = i;
1193						break;
1194						}
1195
1196					event.sctp_sender_dry_event = 0;
1197
1198					i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
1199					if (i < 0)
1200						{
1201						ret = i;
1202						break;
1203						}
1204#endif
1205					}
1206
1207#ifdef SCTP_AUTHENTICATION_EVENT
1208				if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1209					dgram_sctp_handle_auth_free_key_event(b, snp);
1210#endif
1211
1212				if (data->handle_notifications != NULL)
1213					data->handle_notifications(b, data->notification_context, (void*) out);
1214
1215				memset(out, 0, outl);
1216				}
1217			else
1218				ret += n;
1219			}
1220		while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl));
1221
1222		if (ret > 0 && !(msg.msg_flags & MSG_EOR))
1223			{
1224			/* Partial message read, this should never happen! */
1225
1226			/* The buffer was too small, this means the peer sent
1227			 * a message that was larger than allowed. */
1228			if (ret == outl)
1229				return -1;
1230
1231			/* Test if socket buffer can handle max record
1232			 * size (2^14 + 2048 + 13)
1233			 */
1234			optlen = (socklen_t) sizeof(int);
1235			ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
1236			if (ret >= 0)
1237				OPENSSL_assert(optval >= 18445);
1238
1239			/* Test if SCTP doesn't partially deliver below
1240			 * max record size (2^14 + 2048 + 13)
1241			 */
1242			optlen = (socklen_t) sizeof(int);
1243			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
1244			                 &optval, &optlen);
1245			if (ret >= 0)
1246				OPENSSL_assert(optval >= 18445);
1247
1248			/* Partially delivered notification??? Probably a bug.... */
1249			OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
1250
1251			/* Everything seems ok till now, so it's most likely
1252			 * a message dropped by PR-SCTP.
1253			 */
1254			memset(out, 0, outl);
1255			BIO_set_retry_read(b);
1256			return -1;
1257			}
1258
1259		BIO_clear_retry_flags(b);
1260		if (ret < 0)
1261			{
1262			if (BIO_dgram_should_retry(ret))
1263				{
1264				BIO_set_retry_read(b);
1265				data->_errno = get_last_socket_error();
1266				}
1267			}
1268
1269		/* Test if peer uses SCTP-AUTH before continuing */
1270		if (!data->peer_auth_tested)
1271			{
1272			int ii, auth_data = 0, auth_forward = 0;
1273			unsigned char *p;
1274			struct sctp_authchunks *authchunks;
1275
1276			optlen = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
1277			authchunks = OPENSSL_malloc(optlen);
1278			memset(authchunks, 0, sizeof(optlen));
1279			ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen);
1280
1281			if (ii >= 0)
1282				for (p = (unsigned char*) authchunks->gauth_chunks;
1283				     p < (unsigned char*) authchunks + optlen;
1284				     p += sizeof(uint8_t))
1285					{
1286					if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1;
1287					if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1;
1288					}
1289
1290			OPENSSL_free(authchunks);
1291
1292			if (!auth_data || !auth_forward)
1293				{
1294				BIOerr(BIO_F_DGRAM_SCTP_READ,BIO_R_CONNECT_ERROR);
1295				return -1;
1296				}
1297
1298			data->peer_auth_tested = 1;
1299			}
1300		}
1301	return(ret);
1302	}
1303
1304static int dgram_sctp_write(BIO *b, const char *in, int inl)
1305	{
1306	int ret;
1307	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
1308	struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
1309	struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
1310	struct bio_dgram_sctp_sndinfo handshake_sinfo;
1311	struct iovec iov[1];
1312	struct msghdr msg;
1313	struct cmsghdr *cmsg;
1314#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1315	char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + CMSG_SPACE(sizeof(struct sctp_prinfo))];
1316	struct sctp_sndinfo *sndinfo;
1317	struct sctp_prinfo *prinfo;
1318#else
1319	char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
1320	struct sctp_sndrcvinfo *sndrcvinfo;
1321#endif
1322
1323	clear_socket_error();
1324
1325	/* If we're send anything else than application data,
1326	 * disable all user parameters and flags.
1327	 */
1328	if (in[0] != 23) {
1329		memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo));
1330#ifdef SCTP_SACK_IMMEDIATELY
1331		handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
1332#endif
1333		sinfo = &handshake_sinfo;
1334	}
1335
1336	/* If we have to send a shutdown alert message and the
1337	 * socket is not dry yet, we have to save it and send it
1338	 * as soon as the socket gets dry.
1339	 */
1340	if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b))
1341	{
1342		data->saved_message.bio = b;
1343		if (data->saved_message.data)
1344			OPENSSL_free(data->saved_message.data);
1345		data->saved_message.data = OPENSSL_malloc(inl);
1346		memcpy(data->saved_message.data, in, inl);
1347		data->saved_message.length = inl;
1348		return inl;
1349	}
1350
1351	iov[0].iov_base = (char *)in;
1352	iov[0].iov_len = inl;
1353	msg.msg_name = NULL;
1354	msg.msg_namelen = 0;
1355	msg.msg_iov = iov;
1356	msg.msg_iovlen = 1;
1357	msg.msg_control = (caddr_t)cmsgbuf;
1358	msg.msg_controllen = 0;
1359	msg.msg_flags = 0;
1360#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1361	cmsg = (struct cmsghdr *)cmsgbuf;
1362	cmsg->cmsg_level = IPPROTO_SCTP;
1363	cmsg->cmsg_type = SCTP_SNDINFO;
1364	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
1365	sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
1366	memset(sndinfo, 0, sizeof(struct sctp_sndinfo));
1367	sndinfo->snd_sid = sinfo->snd_sid;
1368	sndinfo->snd_flags = sinfo->snd_flags;
1369	sndinfo->snd_ppid = sinfo->snd_ppid;
1370	sndinfo->snd_context = sinfo->snd_context;
1371	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
1372
1373	cmsg = (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
1374	cmsg->cmsg_level = IPPROTO_SCTP;
1375	cmsg->cmsg_type = SCTP_PRINFO;
1376	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
1377	prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
1378	memset(prinfo, 0, sizeof(struct sctp_prinfo));
1379	prinfo->pr_policy = pinfo->pr_policy;
1380	prinfo->pr_value = pinfo->pr_value;
1381	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
1382#else
1383	cmsg = (struct cmsghdr *)cmsgbuf;
1384	cmsg->cmsg_level = IPPROTO_SCTP;
1385	cmsg->cmsg_type = SCTP_SNDRCV;
1386	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
1387	sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1388	memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
1389	sndrcvinfo->sinfo_stream = sinfo->snd_sid;
1390	sndrcvinfo->sinfo_flags = sinfo->snd_flags;
1391#ifdef __FreeBSD__
1392	sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
1393#endif
1394	sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
1395	sndrcvinfo->sinfo_context = sinfo->snd_context;
1396	sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
1397	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
1398#endif
1399
1400	ret = sendmsg(b->num, &msg, 0);
1401
1402	BIO_clear_retry_flags(b);
1403	if (ret <= 0)
1404		{
1405		if (BIO_dgram_should_retry(ret))
1406			{
1407			BIO_set_retry_write(b);
1408			data->_errno = get_last_socket_error();
1409			}
1410		}
1411	return(ret);
1412	}
1413
1414static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1415	{
1416	long ret=1;
1417	bio_dgram_sctp_data *data = NULL;
1418	socklen_t sockopt_len = 0;
1419	struct sctp_authkeyid authkeyid;
1420	struct sctp_authkey *authkey = NULL;
1421
1422	data = (bio_dgram_sctp_data *)b->ptr;
1423
1424	switch (cmd)
1425		{
1426	case BIO_CTRL_DGRAM_QUERY_MTU:
1427		/* Set to maximum (2^14)
1428		 * and ignore user input to enable transport
1429		 * protocol fragmentation.
1430		 * Returns always 2^14.
1431		 */
1432		data->mtu = 16384;
1433		ret = data->mtu;
1434		break;
1435	case BIO_CTRL_DGRAM_SET_MTU:
1436		/* Set to maximum (2^14)
1437		 * and ignore input to enable transport
1438		 * protocol fragmentation.
1439		 * Returns always 2^14.
1440		 */
1441		data->mtu = 16384;
1442		ret = data->mtu;
1443		break;
1444	case BIO_CTRL_DGRAM_SET_CONNECTED:
1445	case BIO_CTRL_DGRAM_CONNECT:
1446		/* Returns always -1. */
1447		ret = -1;
1448		break;
1449	case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
1450		/* SCTP doesn't need the DTLS timer
1451		 * Returns always 1.
1452		 */
1453		break;
1454	case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
1455		/* We allow transport protocol fragmentation so this is irrelevant */
1456		ret = 0;
1457		break;
1458	case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
1459		if (num > 0)
1460			data->in_handshake = 1;
1461		else
1462			data->in_handshake = 0;
1463
1464		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY, &data->in_handshake, sizeof(int));
1465		break;
1466	case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
1467		/* New shared key for SCTP AUTH.
1468		 * Returns 0 on success, -1 otherwise.
1469		 */
1470
1471		/* Get active key */
1472		sockopt_len = sizeof(struct sctp_authkeyid);
1473		ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1474		if (ret < 0) break;
1475
1476		/* Add new key */
1477		sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
1478		authkey = OPENSSL_malloc(sockopt_len);
1479		if (authkey == NULL)
1480			{
1481			ret = -1;
1482			break;
1483			}
1484		memset(authkey, 0x00, sockopt_len);
1485		authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
1486#ifndef __FreeBSD__
1487		/* This field is missing in FreeBSD 8.2 and earlier,
1488		 * and FreeBSD 8.3 and higher work without it.
1489		 */
1490		authkey->sca_keylength = 64;
1491#endif
1492		memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
1493
1494		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len);
1495		OPENSSL_free(authkey);
1496		authkey = NULL;
1497		if (ret < 0) break;
1498
1499		/* Reset active key */
1500		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1501		      &authkeyid, sizeof(struct sctp_authkeyid));
1502		if (ret < 0) break;
1503
1504		break;
1505	case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
1506		/* Returns 0 on success, -1 otherwise. */
1507
1508		/* Get active key */
1509		sockopt_len = sizeof(struct sctp_authkeyid);
1510		ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1511		if (ret < 0) break;
1512
1513		/* Set active key */
1514		authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
1515		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1516		      &authkeyid, sizeof(struct sctp_authkeyid));
1517		if (ret < 0) break;
1518
1519		/* CCS has been sent, so remember that and fall through
1520		 * to check if we need to deactivate an old key
1521		 */
1522		data->ccs_sent = 1;
1523
1524	case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
1525		/* Returns 0 on success, -1 otherwise. */
1526
1527		/* Has this command really been called or is this just a fall-through? */
1528		if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
1529			data->ccs_rcvd = 1;
1530
1531		/* CSS has been both, received and sent, so deactivate an old key */
1532		if (data->ccs_rcvd == 1 && data->ccs_sent == 1)
1533			{
1534			/* Get active key */
1535			sockopt_len = sizeof(struct sctp_authkeyid);
1536			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1537			if (ret < 0) break;
1538
1539			/* Deactivate key or delete second last key if
1540			 * SCTP_AUTHENTICATION_EVENT is not available.
1541			 */
1542			authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
1543#ifdef SCTP_AUTH_DEACTIVATE_KEY
1544			sockopt_len = sizeof(struct sctp_authkeyid);
1545			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
1546			      &authkeyid, sockopt_len);
1547			if (ret < 0) break;
1548#endif
1549#ifndef SCTP_AUTHENTICATION_EVENT
1550			if (authkeyid.scact_keynumber > 0)
1551				{
1552				authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
1553				ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
1554					  &authkeyid, sizeof(struct sctp_authkeyid));
1555				if (ret < 0) break;
1556				}
1557#endif
1558
1559			data->ccs_rcvd = 0;
1560			data->ccs_sent = 0;
1561			}
1562		break;
1563	case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
1564		/* Returns the size of the copied struct. */
1565		if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo))
1566			num = sizeof(struct bio_dgram_sctp_sndinfo);
1567
1568		memcpy(ptr, &(data->sndinfo), num);
1569		ret = num;
1570		break;
1571	case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
1572		/* Returns the size of the copied struct. */
1573		if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo))
1574			num = sizeof(struct bio_dgram_sctp_sndinfo);
1575
1576		memcpy(&(data->sndinfo), ptr, num);
1577		break;
1578	case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
1579		/* Returns the size of the copied struct. */
1580		if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
1581			num = sizeof(struct bio_dgram_sctp_rcvinfo);
1582
1583		memcpy(ptr, &data->rcvinfo, num);
1584
1585		ret = num;
1586		break;
1587	case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
1588		/* Returns the size of the copied struct. */
1589		if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
1590			num = sizeof(struct bio_dgram_sctp_rcvinfo);
1591
1592		memcpy(&(data->rcvinfo), ptr, num);
1593		break;
1594	case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
1595		/* Returns the size of the copied struct. */
1596		if (num > (long) sizeof(struct bio_dgram_sctp_prinfo))
1597			num = sizeof(struct bio_dgram_sctp_prinfo);
1598
1599		memcpy(ptr, &(data->prinfo), num);
1600		ret = num;
1601		break;
1602	case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
1603		/* Returns the size of the copied struct. */
1604		if (num > (long) sizeof(struct bio_dgram_sctp_prinfo))
1605			num = sizeof(struct bio_dgram_sctp_prinfo);
1606
1607		memcpy(&(data->prinfo), ptr, num);
1608		break;
1609	case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
1610		/* Returns always 1. */
1611		if (num > 0)
1612			data->save_shutdown = 1;
1613		else
1614			data->save_shutdown = 0;
1615		break;
1616
1617	default:
1618		/* Pass to default ctrl function to
1619		 * process SCTP unspecific commands
1620		 */
1621		ret=dgram_ctrl(b, cmd, num, ptr);
1622		break;
1623		}
1624	return(ret);
1625	}
1626
1627int BIO_dgram_sctp_notification_cb(BIO *b,
1628                                   void (*handle_notifications)(BIO *bio, void *context, void *buf),
1629                                   void *context)
1630	{
1631	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1632
1633	if (handle_notifications != NULL)
1634		{
1635		data->handle_notifications = handle_notifications;
1636		data->notification_context = context;
1637		}
1638	else
1639		return -1;
1640
1641	return 0;
1642	}
1643
1644int BIO_dgram_sctp_wait_for_dry(BIO *b)
1645{
1646	int is_dry = 0;
1647	int n, sockflags, ret;
1648	union sctp_notification snp;
1649	struct msghdr msg;
1650	struct iovec iov;
1651#ifdef SCTP_EVENT
1652	struct sctp_event event;
1653#else
1654	struct sctp_event_subscribe event;
1655	socklen_t eventsize;
1656#endif
1657	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
1658
1659	/* set sender dry event */
1660#ifdef SCTP_EVENT
1661	memset(&event, 0, sizeof(struct sctp_event));
1662	event.se_assoc_id = 0;
1663	event.se_type = SCTP_SENDER_DRY_EVENT;
1664	event.se_on = 1;
1665	ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
1666#else
1667	eventsize = sizeof(struct sctp_event_subscribe);
1668	ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1669	if (ret < 0)
1670		return -1;
1671
1672	event.sctp_sender_dry_event = 1;
1673
1674	ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
1675#endif
1676	if (ret < 0)
1677		return -1;
1678
1679	/* peek for notification */
1680	memset(&snp, 0x00, sizeof(union sctp_notification));
1681	iov.iov_base = (char *)&snp;
1682	iov.iov_len = sizeof(union sctp_notification);
1683	msg.msg_name = NULL;
1684	msg.msg_namelen = 0;
1685	msg.msg_iov = &iov;
1686	msg.msg_iovlen = 1;
1687	msg.msg_control = NULL;
1688	msg.msg_controllen = 0;
1689	msg.msg_flags = 0;
1690
1691	n = recvmsg(b->num, &msg, MSG_PEEK);
1692	if (n <= 0)
1693		{
1694		if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
1695			return -1;
1696		else
1697			return 0;
1698		}
1699
1700	/* if we find a notification, process it and try again if necessary */
1701	while (msg.msg_flags & MSG_NOTIFICATION)
1702		{
1703		memset(&snp, 0x00, sizeof(union sctp_notification));
1704		iov.iov_base = (char *)&snp;
1705		iov.iov_len = sizeof(union sctp_notification);
1706		msg.msg_name = NULL;
1707		msg.msg_namelen = 0;
1708		msg.msg_iov = &iov;
1709		msg.msg_iovlen = 1;
1710		msg.msg_control = NULL;
1711		msg.msg_controllen = 0;
1712		msg.msg_flags = 0;
1713
1714		n = recvmsg(b->num, &msg, 0);
1715		if (n <= 0)
1716			{
1717			if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
1718				return -1;
1719			else
1720				return is_dry;
1721			}
1722
1723		if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
1724			{
1725			is_dry = 1;
1726
1727			/* disable sender dry event */
1728#ifdef SCTP_EVENT
1729			memset(&event, 0, sizeof(struct sctp_event));
1730			event.se_assoc_id = 0;
1731			event.se_type = SCTP_SENDER_DRY_EVENT;
1732			event.se_on = 0;
1733			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
1734#else
1735			eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
1736			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1737			if (ret < 0)
1738				return -1;
1739
1740			event.sctp_sender_dry_event = 0;
1741
1742			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
1743#endif
1744			if (ret < 0)
1745				return -1;
1746			}
1747
1748#ifdef SCTP_AUTHENTICATION_EVENT
1749		if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1750			dgram_sctp_handle_auth_free_key_event(b, &snp);
1751#endif
1752
1753		if (data->handle_notifications != NULL)
1754			data->handle_notifications(b, data->notification_context, (void*) &snp);
1755
1756		/* found notification, peek again */
1757		memset(&snp, 0x00, sizeof(union sctp_notification));
1758		iov.iov_base = (char *)&snp;
1759		iov.iov_len = sizeof(union sctp_notification);
1760		msg.msg_name = NULL;
1761		msg.msg_namelen = 0;
1762		msg.msg_iov = &iov;
1763		msg.msg_iovlen = 1;
1764		msg.msg_control = NULL;
1765		msg.msg_controllen = 0;
1766		msg.msg_flags = 0;
1767
1768		/* if we have seen the dry already, don't wait */
1769		if (is_dry)
1770			{
1771			sockflags = fcntl(b->num, F_GETFL, 0);
1772			fcntl(b->num, F_SETFL, O_NONBLOCK);
1773			}
1774
1775		n = recvmsg(b->num, &msg, MSG_PEEK);
1776
1777		if (is_dry)
1778			{
1779			fcntl(b->num, F_SETFL, sockflags);
1780			}
1781
1782		if (n <= 0)
1783			{
1784			if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
1785				return -1;
1786			else
1787				return is_dry;
1788			}
1789		}
1790
1791	/* read anything else */
1792	return is_dry;
1793}
1794
1795int BIO_dgram_sctp_msg_waiting(BIO *b)
1796	{
1797	int n, sockflags;
1798	union sctp_notification snp;
1799	struct msghdr msg;
1800	struct iovec iov;
1801	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
1802
1803	/* Check if there are any messages waiting to be read */
1804	do
1805		{
1806		memset(&snp, 0x00, sizeof(union sctp_notification));
1807		iov.iov_base = (char *)&snp;
1808		iov.iov_len = sizeof(union sctp_notification);
1809		msg.msg_name = NULL;
1810		msg.msg_namelen = 0;
1811		msg.msg_iov = &iov;
1812		msg.msg_iovlen = 1;
1813		msg.msg_control = NULL;
1814		msg.msg_controllen = 0;
1815		msg.msg_flags = 0;
1816
1817		sockflags = fcntl(b->num, F_GETFL, 0);
1818		fcntl(b->num, F_SETFL, O_NONBLOCK);
1819		n = recvmsg(b->num, &msg, MSG_PEEK);
1820		fcntl(b->num, F_SETFL, sockflags);
1821
1822		/* if notification, process and try again */
1823		if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION))
1824			{
1825#ifdef SCTP_AUTHENTICATION_EVENT
1826			if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1827				dgram_sctp_handle_auth_free_key_event(b, &snp);
1828#endif
1829
1830			memset(&snp, 0x00, sizeof(union sctp_notification));
1831			iov.iov_base = (char *)&snp;
1832			iov.iov_len = sizeof(union sctp_notification);
1833			msg.msg_name = NULL;
1834			msg.msg_namelen = 0;
1835			msg.msg_iov = &iov;
1836			msg.msg_iovlen = 1;
1837			msg.msg_control = NULL;
1838			msg.msg_controllen = 0;
1839			msg.msg_flags = 0;
1840			n = recvmsg(b->num, &msg, 0);
1841
1842			if (data->handle_notifications != NULL)
1843				data->handle_notifications(b, data->notification_context, (void*) &snp);
1844			}
1845
1846		} while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
1847
1848	/* Return 1 if there is a message to be read, return 0 otherwise. */
1849	if (n > 0)
1850		return 1;
1851	else
1852		return 0;
1853	}
1854
1855static int dgram_sctp_puts(BIO *bp, const char *str)
1856	{
1857	int n,ret;
1858
1859	n=strlen(str);
1860	ret=dgram_sctp_write(bp,str,n);
1861	return(ret);
1862	}
1863#endif
1864
1865static int BIO_dgram_should_retry(int i)
1866	{
1867	int err;
1868
1869	if ((i == 0) || (i == -1))
1870		{
1871		err=get_last_socket_error();
1872
1873#if defined(OPENSSL_SYS_WINDOWS)
1874	/* If the socket return value (i) is -1
1875	 * and err is unexpectedly 0 at this point,
1876	 * the error code was overwritten by
1877	 * another system call before this error
1878	 * handling is called.
1879	 */
1880#endif
1881
1882		return(BIO_dgram_non_fatal_error(err));
1883		}
1884	return(0);
1885	}
1886
1887int BIO_dgram_non_fatal_error(int err)
1888	{
1889	switch (err)
1890		{
1891#if defined(OPENSSL_SYS_WINDOWS)
1892# if defined(WSAEWOULDBLOCK)
1893	case WSAEWOULDBLOCK:
1894# endif
1895
1896# if 0 /* This appears to always be an error */
1897#  if defined(WSAENOTCONN)
1898	case WSAENOTCONN:
1899#  endif
1900# endif
1901#endif
1902
1903#ifdef EWOULDBLOCK
1904# ifdef WSAEWOULDBLOCK
1905#  if WSAEWOULDBLOCK != EWOULDBLOCK
1906	case EWOULDBLOCK:
1907#  endif
1908# else
1909	case EWOULDBLOCK:
1910# endif
1911#endif
1912
1913#ifdef EINTR
1914	case EINTR:
1915#endif
1916
1917#ifdef EAGAIN
1918#if EWOULDBLOCK != EAGAIN
1919	case EAGAIN:
1920# endif
1921#endif
1922
1923#ifdef EPROTO
1924	case EPROTO:
1925#endif
1926
1927#ifdef EINPROGRESS
1928	case EINPROGRESS:
1929#endif
1930
1931#ifdef EALREADY
1932	case EALREADY:
1933#endif
1934
1935		return(1);
1936		/* break; */
1937	default:
1938		break;
1939		}
1940	return(0);
1941	}
1942
1943static void get_current_time(struct timeval *t)
1944	{
1945#ifdef OPENSSL_SYS_WIN32
1946	struct _timeb tb;
1947	_ftime(&tb);
1948	t->tv_sec = (long)tb.time;
1949	t->tv_usec = (long)tb.millitm * 1000;
1950#elif defined(OPENSSL_SYS_VMS)
1951	struct timeb tb;
1952	ftime(&tb);
1953	t->tv_sec = (long)tb.time;
1954	t->tv_usec = (long)tb.millitm * 1000;
1955#else
1956	gettimeofday(t, NULL);
1957#endif
1958	}
1959
1960#endif
1961