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