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