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