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