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