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