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